diff --git a/checklists-ext/fullwaf_checklist.en.json b/checklists-ext/fullwaf_checklist.en.json index 70daf38c..5ce918e7 100644 --- a/checklists-ext/fullwaf_checklist.en.json +++ b/checklists-ext/fullwaf_checklist.en.json @@ -1,5 +1,207 @@ { "items": [ + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "High", + "text": "Disable Azure Container Registry image export", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "High", + "text": "Enable Azure Policies for Azure Container Registry", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "High", + "text": "Sign and Verify containers with notation (Notary v2)", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "Medium", + "text": "Encrypt registry with a customer managed key", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "High", + "text": "Use Managed Identities to connect instead of Service Principals", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "High", + "text": "Disable local authentication for management plane access", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "High", + "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable anonymous pull/push access", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "Medium", + "text": "Disable Anonymous pull access", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "High", + "text": "Disable repository-scoped access tokens", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "High", + "text": "Deploy images from a trusted environment", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "Medium", + "text": "Disable Azure ARM audience tokens for authentication", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "Medium", + "text": "Enable diagnostics logging", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "Medium", + "text": "Control inbound network access with Private Link", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable public network access if inbound network access is secured using Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "Medium", + "text": "Disable Public Network access", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Only the ACR Premium SKU supports Private Link access", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "Medium", + "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "Low", + "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "severity": "Medium", + "text": "Deploy validated container images", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "High", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "waf": "Reliability" + }, { "arm-service": "Microsoft.App/containerApps", "checklist": "Container Apps Review", @@ -3647,46 +3849,6 @@ "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Cost" }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "High", - "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", - "severity": "Medium", - "text": "Configure data persistence for an Azure Cache for Redis instance. Because your cache data is stored in memory, a rare and unplanned failure of multiple nodes can cause all the data to be dropped. To avoid losing data completely, Redis persistence allows you to take periodic snapshots of in-memory data, and store it to your storage account.", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", - "severity": "Medium", - "text": "Use Geo-redundant storage account to persist Azure Cache for Redis data, or zonally redundant where geo-redundancy is not available", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", - "severity": "Medium", - "text": "Configure passive geo-replication for Premium Azure Cache for Redis instances. Geo-replication is a mechanism for linking two or more Azure Cache for Redis instances, typically spanning two Azure regions. Geo-replication is designed mainly for cross-region disaster recovery. Two Premium tier cache instances are connected through geo-replication in a way that provides reads and writes to your primary cache, and that data is replicated to the secondary cache.", - "waf": "Reliability" - }, { "arm-service": "microsoft.network/frontdoors", "checklist": "Azure Application Delivery Networking", @@ -6026,208 +6188,6 @@ "text": "Consider using dedicated model deployments per consumer group to provide per-model usage isolation that can help prevent noisy neighbors between your consumer groups", "waf": "Operations" }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", - "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", - "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", - "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", - "service": "ACR", - "severity": "High", - "text": "Disable Azure Container Registry image export", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", - "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", - "service": "ACR", - "severity": "High", - "text": "Enable Azure Policies for Azure Container Registry", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", - "guid": "d345293c-7639-4637-a551-c5c04e401955", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", - "service": "ACR", - "severity": "High", - "text": "Sign and Verify containers with notation (Notary v2)", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", - "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", - "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", - "service": "ACR", - "severity": "Medium", - "text": "Encrypt registry with a customer managed key", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", - "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "service": "ACR", - "severity": "High", - "text": "Use Managed Identities to connect instead of Service Principals", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "guid": "be0e38ce-e297-411b-b363-caaab79b198d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "service": "ACR", - "severity": "High", - "text": "Disable local authentication for management plane access", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", - "service": "ACR", - "severity": "High", - "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable anonymous pull/push access", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", - "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", - "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", - "service": "ACR", - "severity": "Medium", - "text": "Disable Anonymous pull access", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", - "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", - "service": "ACR", - "severity": "High", - "text": "Disable repository-scoped access tokens", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", - "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", - "service": "ACR", - "severity": "High", - "text": "Deploy images from a trusted environment", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", - "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", - "service": "ACR", - "severity": "Medium", - "text": "Disable Azure ARM audience tokens for authentication", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", - "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", - "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", - "service": "ACR", - "severity": "Medium", - "text": "Enable diagnostics logging", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", - "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", - "service": "ACR", - "severity": "Medium", - "text": "Control inbound network access with Private Link", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable public network access if inbound network access is secured using Private Link", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", - "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", - "service": "ACR", - "severity": "Medium", - "text": "Disable Public Network access", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Only the ACR Premium SKU supports Private Link access", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", - "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", - "service": "ACR", - "severity": "Medium", - "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", - "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", - "service": "ACR", - "severity": "Low", - "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", - "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", - "service": "ACR", - "severity": "Medium", - "text": "Deploy validated container images", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", - "guid": "4e401955-387e-45ce-b126-cd132af5b20c", - "service": "ACR", - "severity": "High", - "text": "Use up-to-date platforms, languages, protocols and frameworks", - "waf": "Reliability" - }, { "arm-service": "Microsoft.Kusto/clusters", "checklist": "Azure Data Explorer Review Checklist", @@ -6408,6 +6368,46 @@ "text": "If using Keyvault integration, use SLA of Keyvault to understand your availablity", "waf": "Reliability" }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "High", + "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "Medium", + "text": "Configure data persistence for an Azure Cache for Redis instance. Because your cache data is stored in memory, a rare and unplanned failure of multiple nodes can cause all the data to be dropped. To avoid losing data completely, Redis persistence allows you to take periodic snapshots of in-memory data, and store it to your storage account.", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "Medium", + "text": "Use Geo-redundant storage account to persist Azure Cache for Redis data, or zonally redundant where geo-redundancy is not available", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "Medium", + "text": "Configure passive geo-replication for Premium Azure Cache for Redis instances. Geo-replication is a mechanism for linking two or more Azure Cache for Redis instances, typically spanning two Azure regions. Geo-replication is designed mainly for cross-region disaster recovery. Two Premium tier cache instances are connected through geo-replication in a way that provides reads and writes to your primary cache, and that data is replicated to the secondary cache.", + "waf": "Reliability" + }, { "arm-service": "Microsoft.AVS/privateClouds", "checklist": "Azure VMware Solution Design Review", @@ -7376,6 +7376,7 @@ "description": "Azure Event Hub provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", "guid": "7aaf12e7-b94e-4f6e-847d-2d92981b1cd6", "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend SkuName = tostring(sku.name) | extend EncryptionEnabled = iif(isnotempty(properties.encryption.keySource), 'Enabled', 'Disabled') | extend compliant = iif(EncryptionEnabled == 'Enabled', true, false) | project name, resourceGroup, location, SkuName, EncryptionEnabled, compliant | where SkuName == 'Premium'", "service": "Event Hubs", "severity": "Low", "text": "Use customer-managed key option in data at rest encryption when required", @@ -7388,6 +7389,7 @@ "description": "Azure Event Hubs namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Event Hubs namespace to require that clients send and receive data with a newer version of TLS. If an Event Hubs namespace requires a minimum version of TLS, then any requests made with an older version will fail. ", "guid": "d2f54b29-769e-43a6-a0e7-828ac936657e", "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend MinimumTlsVersion = tostring(properties.minimumTlsVersion) | extend compliant = iif(MinimumTlsVersion == '1.2' or MinimumTlsVersion == '1.3', true, false) | project name, resourceGroup, location, MinimumTlsVersion, compliant", "service": "Event Hubs", "severity": "Medium", "text": "Enforce a minimum required version of Transport Layer Security (TLS) for requests ", @@ -7482,6 +7484,7 @@ "description": " This will be turned on automatically for a new EH namespace created from the portal with Premium, Dedicated, or Standard SKUs in a zone-enabled region. Both the EH metadata and the event data itself are replicated across zones", "guid": "f15bce21-9e4a-40eb-9787-9424d226786d", "link": "https://learn.microsoft.com/azure/event-hubs/event-hubs-premium-overview#high-availability-with-availability-zones", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend zoneRedundant = tobool(properties.zoneRedundant) | extend compliant = iff(zoneRedundant == true, true, false) | project name, resourceGroup, zoneRedundant, compliant", "service": "Event Hubs", "severity": "High", "text": "Leverage Availability Zones if regionally applicable", @@ -7492,6 +7495,7 @@ "checklist": "Azure Event Hub Review", "guid": "20b56c56-ad58-4519-8f82-735c586bb281", "link": "https://learn.microsoft.com/azure/event-hubs/compare-tiers", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend sku = tostring(sku.name) | extend compliant = iff(sku == 'Premium', true, false) | project name, resourceGroup, location, sku, compliant", "service": "Event Hubs", "severity": "Medium", "text": "Use the Premium or Dedicated SKUs for predicable performance", @@ -7923,6 +7927,17 @@ "text": "Restrict use of local users on sql workloads on Synapse", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No additional configurations are required as this is enabled on a default deployment.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Event Hubs", + "severity": "Medium", + "text": "Encrypt sensitive data in transit", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7934,6 +7949,15 @@ "text": "Use managed identity to authenticate to the services", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Event Hubs", + "severity": "Medium", + "text": "Enable data at rest encryption by default", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7944,6 +7968,17 @@ "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Keyvaults to store your CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Event Hubs", + "severity": "Medium", + "text": "Use customer-managed key option in data at rest encryption when required", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7976,6 +8011,16 @@ "text": "Use managed vnet workspace to restrict the access over public internet", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Microsoft Entra ID as the default authentication method.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Event Hubs", + "severity": "High", + "text": "Use Microsoft Entra ID as the default authentication method and disable local access wherever possible", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7987,6 +8032,16 @@ "text": "Configure private endpoints to connect to the external services and disable public access", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Microsoft Entra ID as the default authentication method.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Event Hubs", + "severity": "Medium", + "text": "Use managed identity to authenticate to the services", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7997,6 +8052,15 @@ "text": "If enabling public access highly recommended to configure IP firewall rules", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Event Hubs", + "severity": "Medium", + "text": "Configure conditional access policies to restrict the access on Data plane", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8007,6 +8071,16 @@ "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn�t leave your corporate network", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Restrict exposure of keys and secerts", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Event Hubs", + "severity": "High", + "text": "Use Azure Key Vaults to store secrets and crendentials.", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8018,6 +8092,37 @@ "text": "Enable Data Exfiltration Protection (DEP)", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Event Hubs", + "severity": "High", + "text": "Separate and limit highly privileged/administrative users", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It�s recommended that you treat this rule like an administrative root account and don�t use it in your application. You can create additional policy rules in the Configure tab for the namespace in the portal, via PowerShell or Azure CLI. Avoid the usage of local authentication methods or accounts, these should be disabled wherever possible. Instead use Azure AD to authenticate where possible.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Event Hubs", + "severity": "Medium", + "text": "Authenticate access to Event Hubs resources using shared access signatures (SAS) and restrict local users", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Azure role-based access control (Azure RBAC) to manage Azure resource access through built-in role assignments. Azure RBAC roles can be assigned to users, groups, service principals, and managed identities.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Event Hubs", + "severity": "Medium", + "text": "Use Azure RBACs to fine grain the access ", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8029,6 +8134,16 @@ "text": "Data Encryption at rest using Customer managed Keys for workspace", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Event Hubs", + "severity": "Medium", + "text": "Disable Public Network Access", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8040,6 +8155,15 @@ "text": "Data Encryption in transit ", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Event Hubs", + "severity": "Medium", + "text": "Use Vnets to isolate traffic over restricted network ", + "waf": "Reliability" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8050,6 +8174,16 @@ "text": "Store passwords, secerts and keys in Azure key vault", "waf": "Reliability" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Event Hubs", + "severity": "Medium", + "text": "Deploy private endpoints for all Azure resources that support the Private Link feature, to establish a private access point for the resources.", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8061,6 +8195,90 @@ "text": "Use Azure Key Vault secrets in pipeline activities", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric controls data access using workspaces. In workspaces, data appears in the form of Fabric items, and users can't view or use items (data) unless you give them access to the workspace. You can find more information about workspace and item permissions, in Permission model.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use Workspace roles to provide access to the users on the data", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "OneLake RBAC uses role assignments to apply permissions to its members.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use RBAC on Onelake to provide fine grain access on the data in Tables/Files Onelake ", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Take into account the access of the user at both target and source location of the shortcut", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "When using shortcuts the user identity of the user should have access on the target location of the shortcut as well", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Not all users need to have access on the entire workspace using roles so instead restrict giving roles on the entire workspace and only share the item to the user using share item feature or managing permission in Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Restrict providing workspace level role to users instead share an item only to the users", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use features like RLS, CLS and Dynamic data masking to enhance your data security requirements on sql workloads.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Limit access to the data by defining RLS, CLS and dynamic data masking on Warehouse and SQL analytics endpoints", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use features like RLS and OLS on Power BI to have more security features on semantic models", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Limit access to the data by defining RLS and OLS on semantic models in Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "In Fabric, all data that is stored in OneLake is encrypted at rest", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Encrypt Data at rest", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Data in transit across the public internet between Microsoft services is always encrypted with at least TLS 1.2. Fabric negotiates to TLS 1.3 whenever possible.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Encrypt data in transit", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8071,6 +8289,16 @@ "text": "Restrict use of local users whereever necessary", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No need to do anything. Every request to connect to Fabric is authenticated with Microsoft Entra ID, allowing users to safely connect to Fabric from their corporate office, when working at home, or from a remote location.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use Microsoft Entra ID as default authentication method", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8082,6 +8310,16 @@ "text": "Use managed identity to authenticate to the services", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "A Fabric workspace identity is an automatically managed service principal that can be associated with a Fabric workspace. Workspace identities can be created in the workspace settings of any workspace except My workspaces. A workspace identity is automatically assigned the workspace contributor role and has access to workspace items. Limitation: Write to shortcut destination fails when using workspace identity as the authentication method. Connections with workspace-identity-authentication can only be used in Onelake shortcuts and data pipelines.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use workspace identity to authenticate to the services", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8092,6 +8330,16 @@ "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Grant the identity permissions on the storage account", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Provide RBAC roles on storage account to the managed identity to make a successful connection", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8101,6 +8349,16 @@ "text": "Disable access over public internet and configure either firewall rules or trusted services rules", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric workspaces with a workspace identity can securely read or write to firewall-enabled Azure Data Lake Storage Gen2 accounts through�trusted workspace access�for OneLake shortcuts.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure trusted workspace access to access storage account behind firewall ", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8110,6 +8368,17 @@ "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn�t leave your corporate network", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Managed virtual networks are virtual networks that are created and managed by Microsoft Fabric for each Fabric workspace. Managed virtual networks provide network isolation for Fabric Spark workloads, meaning that the compute clusters are deployed in a dedicated network and are no longer part of the shared virtual network. It is only supported for spark workload in Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use managed vnet option if you have network isolation needs", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8120,6 +8389,17 @@ "text": "Use managed vnet IR to restrict the access over public internet for Azure Integration Runtime", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Managed private endpoints are feature that allows secure and private access to data sources from Fabric Spark workloads. You cannot use starter pool with managed PE", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure managed private endpoints to access Azure services", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8131,6 +8411,71 @@ "text": "Configure managed private endpoints to connect to resources using managed azure IR", "waf": "Reliability" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric uses a private IP address from your virtual network. The endpoint allows users in your network to communicate with Fabric over the private IP address using private links.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure Private Links to access resources in your own Azure vnet i.e traffic coming in your Fabric environment", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "When a user authenticates access is determined based on a set of policies that might include IP address, location, and managed devices.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure Microsoft Entra ID conditional access if a user is trying to access your Fabric environment", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "In Azure, a service tag is a defined group of IP addresses that is automatically managed, as a group, to minimize the complexity of updates or changes to network security rules.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "You can use Azure service tags to enable connections to and from Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "optional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "You can add Fabric URLs to your allowlist", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "optional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "You can add Power BI URLs to your allowlist", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Reliability" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "The data gateway lets you connect your Azure and other data services to Microsoft Fabric and the Power Platform to securely communicate with the data source, execute queries, and transmit results back to the service.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure and use On-prem data gateway or Vnet data gateway to connect to sources either on prem or behind a virtual network", + "waf": "Reliability" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -27130,7 +27475,7 @@ ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/acr_checklist.en.json b/checklists/acr_checklist.en.json index 6a200c26..1c30f04f 100644 --- a/checklists/acr_checklist.en.json +++ b/checklists/acr_checklist.en.json @@ -1,323 +1,323 @@ { - "items": [ - { - "category": "Security", - "subcategory": "Data Protection", - "text": "Disable Azure Container Registry image export", - "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", - "waf": "Security", - "service": "ACR", - "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", - "id": "A01.01", - "severity": "High", - "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", - "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention" - }, - { - "category": "Security", - "subcategory": "Data Protection", - "text": "Enable Azure Policies for Azure Container Registry", - "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", - "waf": "Security", - "service": "ACR", - "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", - "id": "A01.02", - "severity": "High", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy" - }, - { - "category": "Security", - "subcategory": "Data Protection", - "text": "Sign and Verify containers with notation (Notary v2)", - "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", - "waf": "Security", - "service": "ACR", - "guid": "d345293c-7639-4637-a551-c5c04e401955", - "id": "A01.03", - "severity": "High", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push" - }, - { - "category": "Security", - "subcategory": "Data Protection", - "text": "Encrypt registry with a customer managed key", - "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", - "waf": "Security", - "service": "ACR", - "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", - "id": "A01.04", - "severity": "Medium", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", - "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identities to connect instead of Service Principals", - "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", - "waf": "Security", - "service": "ACR", - "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", - "id": "A02.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Disable local authentication for management plane access", - "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", - "waf": "Security", - "service": "ACR", - "guid": "be0e38ce-e297-411b-b363-caaab79b198d", - "id": "A02.02", - "severity": "High", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", - "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", - "waf": "Security", - "service": "ACR", - "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", - "id": "A02.03", - "severity": "High", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Disable Anonymous pull access", - "description": "Disable anonymous pull/push access", - "waf": "Security", - "service": "ACR", - "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", - "id": "A02.04", - "severity": "Medium", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant" , - "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Disable repository-scoped access tokens", - "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", - "waf": "Security", - "service": "ACR", - "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", - "id": "A02.05", - "severity": "High", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Deploy images from a trusted environment", - "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", - "waf": "Security", - "service": "ACR", - "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", - "id": "A02.06", - "severity": "High" - }, - { - "category": "Security", - "subcategory": "Identity and Access Control", - "text": "Disable Azure ARM audience tokens for authentication", - "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", - "waf": "Security", - "service": "ACR", - "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", - "id": "A02.07", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy" - }, - { - "category": "Security", - "subcategory": "Logging and Monitoring", - "text": "Enable diagnostics logging", - "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", - "waf": "Security", - "service": "ACR", - "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", - "id": "A03.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/container-registry/monitor-service" - }, - { - "category": "Security", - "subcategory": "Network Security", - "text": "Control inbound network access with Private Link", - "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", - "waf": "Security", - "service": "ACR", - "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", - "id": "A04.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link" - }, - { - "category": "Security", - "subcategory": "Network Security", - "text": "Disable Public Network access", - "description": "Disable public network access if inbound network access is secured using Private Link", - "waf": "Security", - "service": "ACR", - "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", - "id": "A04.02", - "severity": "Medium", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access" - }, - { - "category": "Security", - "subcategory": "Network Security", - "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", - "description": "Only the ACR Premium SKU supports Private Link access", - "waf": "Security", - "service": "ACR", - "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", - "id": "A04.03", - "severity": "Medium", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus" - }, - { - "category": "Security", - "subcategory": "Network Security", - "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", - "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", - "waf": "Security", - "service": "ACR", - "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", - "id": "A04.04", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction" - }, - { - "category": "Security", - "subcategory": "Vulnerability Management", - "text": "Deploy validated container images", - "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", - "waf": "Security", - "service": "ACR", - "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", - "id": "A05.01", - "severity": "Medium" - }, - { - "category": "Security", - "subcategory": "Vulnerability Management", - "text": "Use up-to-date platforms, languages, protocols and frameworks", - "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", - "waf": "Security", - "service": "ACR", - "guid": "4e401955-387e-45ce-b126-cd132af5b20c", - "id": "A05.02", - "severity": "High" + "items": [ + { + "category": "Security", + "subcategory": "Data Protection", + "text": "Disable Azure Container Registry image export", + "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", + "waf": "Security", + "service": "ACR", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "id": "A01.01", + "severity": "High", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention" + }, + { + "category": "Security", + "subcategory": "Data Protection", + "text": "Enable Azure Policies for Azure Container Registry", + "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", + "waf": "Security", + "service": "ACR", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "id": "A01.02", + "severity": "High", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy" + }, + { + "category": "Security", + "subcategory": "Data Protection", + "text": "Sign and Verify containers with notation (Notary v2)", + "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", + "waf": "Security", + "service": "ACR", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "id": "A01.03", + "severity": "High", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push" + }, + { + "category": "Security", + "subcategory": "Data Protection", + "text": "Encrypt registry with a customer managed key", + "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", + "waf": "Security", + "service": "ACR", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "id": "A01.04", + "severity": "Medium", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Use Managed Identities to connect instead of Service Principals", + "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", + "waf": "Security", + "service": "ACR", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Disable local authentication for management plane access", + "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", + "waf": "Security", + "service": "ACR", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", + "severity": "High", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", + "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", + "waf": "Security", + "service": "ACR", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", + "severity": "High", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Disable Anonymous pull access", + "description": "Disable anonymous pull/push access", + "waf": "Security", + "service": "ACR", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", + "severity": "Medium", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Disable repository-scoped access tokens", + "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", + "waf": "Security", + "service": "ACR", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", + "severity": "High", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Deploy images from a trusted environment", + "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", + "waf": "Security", + "service": "ACR", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "severity": "High" + }, + { + "category": "Security", + "subcategory": "Identity and Access Control", + "text": "Disable Azure ARM audience tokens for authentication", + "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", + "waf": "Security", + "service": "ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy" + }, + { + "category": "Security", + "subcategory": "Logging and Monitoring", + "text": "Enable diagnostics logging", + "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", + "waf": "Security", + "service": "ACR", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service" + }, + { + "category": "Security", + "subcategory": "Network Security", + "text": "Control inbound network access with Private Link", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", + "waf": "Security", + "service": "ACR", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link" + }, + { + "category": "Security", + "subcategory": "Network Security", + "text": "Disable Public Network access", + "description": "Disable public network access if inbound network access is secured using Private Link", + "waf": "Security", + "service": "ACR", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", + "severity": "Medium", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access" + }, + { + "category": "Security", + "subcategory": "Network Security", + "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", + "description": "Only the ACR Premium SKU supports Private Link access", + "waf": "Security", + "service": "ACR", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", + "severity": "Medium", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus" + }, + { + "category": "Security", + "subcategory": "Network Security", + "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", + "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", + "waf": "Security", + "service": "ACR", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction" + }, + { + "category": "Security", + "subcategory": "Vulnerability Management", + "text": "Deploy validated container images", + "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", + "waf": "Security", + "service": "ACR", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "severity": "Medium" + }, + { + "category": "Security", + "subcategory": "Vulnerability Management", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", + "waf": "Security", + "service": "ACR", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", + "severity": "High" + } + ], + "categories": [ + { + "name": "Security" + }, + { + "name": "Network topology and connectivity" + }, + { + "name": "Operations management" + }, + { + "name": "Platform Automation" + }, + { + "name": "Security" + }, + { + "name": "Ledger" + }, + { + "name": "Logging" + }, + { + "name": "Networking" + }, + { + "name": "Data Discovery and Classification" + }, + { + "name": "Data Masking" + }, + { + "name": "Code" + } + ], + "waf": [ + { + "name": "Reliability" + }, + { + "name": "Security" + }, + { + "name": "Cost" + }, + { + "name": "Operations" + }, + { + "name": "Performance" + } + ], + "yesno": [ + { + "name": "Yes" + }, + { + "name": "No" + } + ], + "status": [ + { + "name": "Not verified", + "description": "This check has not been looked at yet" + }, + { + "name": "Open", + "description": "There is an action item associated to this check" + }, + { + "name": "Fulfilled", + "description": "This check has been verified, and there are no further action items associated to it" + }, + { + "name": "N/A", + "description": "Not applicable for current design" + }, + { + "name": "Not required", + "description": "Not required" + } + ], + "severities": [ + { + "name": "High" + }, + { + "name": "Medium" + }, + { + "name": "Low" + } + ], + "metadata": { + "name": "Azure Container Registry Security Review", + "waf": "security", + "state": "Preview", + "timestamp": "October 23, 2024" } - ], - "categories": [ - { - "name": "Security" - }, - { - "name": "Network topology and connectivity" - }, - { - "name": "Operations management" - }, - { - "name": "Platform Automation" - }, - { - "name": "Security" - }, - { - "name": "Ledger" - }, - { - "name": "Logging" - }, - { - "name": "Networking" - }, - { - "name": "Data Discovery and Classification" - }, - { - "name": "Data Masking" - }, - { - "name": "Code" - } - ], - "waf": [ - { - "name": "Reliability" - }, - { - "name": "Security" - }, - { - "name": "Cost" - }, - { - "name": "Operations" - }, - { - "name": "Performance" - } - ], - "yesno": [ - { - "name": "Yes" - }, - { - "name": "No" - } - ], - "status": [ - { - "name": "Not verified", - "description": "This check has not been looked at yet" - }, - { - "name": "Open", - "description": "There is an action item associated to this check" - }, - { - "name": "Fulfilled", - "description": "This check has been verified, and there are no further action items associated to it" - }, - { - "name": "N/A", - "description": "Not applicable for current design" - }, - { - "name": "Not required", - "description": "Not required" - } - ], - "severities": [ - { - "name": "High" - }, - { - "name": "Medium" - }, - { - "name": "Low" - } - ], - "metadata": { - "name": "Azure Container Registry Security Review", - "waf": "security", - "state": "Preview", - "timestamp": "10/20/2023 11:39:37" - } -} +} \ No newline at end of file diff --git a/checklists/acr_checklist.es.json b/checklists/acr_checklist.es.json index 0ed94782..cd14740c 100644 --- a/checklists/acr_checklist.es.json +++ b/checklists/acr_checklist.es.json @@ -2,171 +2,265 @@ "categories": [ { "name": "Seguridad" + }, + { + "name": "Topología de red y conectividad" + }, + { + "name": "Gestión de operaciones" + }, + { + "name": "Automatización de plataformas" + }, + { + "name": "Seguridad" + }, + { + "name": "Libro mayor" + }, + { + "name": "Registro" + }, + { + "name": "Gestión de redes" + }, + { + "name": "Detección y clasificación de datos" + }, + { + "name": "Enmascaramiento de datos" + }, + { + "name": "Código" } ], "items": [ { "category": "Seguridad", - "description": "Desactive la exportación de imágenes para evitar la exfiltración de datos. Tenga en cuenta que esto evitará la importación de imágenes a otra instancia de ACR.", + "description": "Deshabilite la exportación de imágenes para evitar la exfiltración de datos. Tenga en cuenta que esto evitará la importación de imágenes a otra instancia de ACR.", "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "id": "A01.01", "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", "severity": "Alto", "subcategory": "Protección de datos", - "text": "Deshabilitar la exportación de imágenes de Azure Container Registry" + "text": "Deshabilitación de la exportación de imágenes de Azure Container Registry", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Habilitar la visibilidad del cumplimiento de auditoría habilitando Azure Policy for Azur eContainer Registry", + "description": "Habilite la visibilidad del cumplimiento de auditorías mediante la habilitación de Azure Policy para Azure Container Registry", "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "id": "A01.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", "severity": "Alto", "subcategory": "Protección de datos", - "text": "Habilitación de directivas de Azure para Azure Container Registry" + "text": "Habilitación de Azure Policies para Azure Container Registry", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Azure Key Vault (AKV) se usa para almacenar una clave de firma que se puede utilizar mediante notación con el complemento de notación AKV (azure-kv) para firmar y comprobar imágenes de contenedor y otros artefactos. Azure Container Registry (ACR) permite adjuntar estas firmas mediante los comandos az u oras CLI.", + "description": "Azure Key Vault (AKV) se usa para almacenar una clave de firma que se puede usar mediante la notación con el complemento de notación AKV (azure-kv) para firmar y comprobar imágenes de contenedor y otros artefactos. Azure Container Registry (ACR) le permite adjuntar estas firmas mediante el ?az?or?oras? Comandos de la CLI.", "guid": "d345293c-7639-4637-a551-c5c04e401955", + "id": "A01.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", "severity": "Alto", "subcategory": "Protección de datos", - "text": "Firmar y verificar contenedores con notación (Notario v2)" + "text": "Firmar y verificar contenedores con notación (Notary v2)", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Azure Container Registry cifra automáticamente las imágenes y otros artefactos que almacena. De forma predeterminada, Azure cifra automáticamente el contenido del Registro en reposo mediante claves administradas por el servicio. Mediante el uso de una clave administrada por el cliente, puede complementar el cifrado predeterminado con una capa de cifrado adicional.", + "description": "Azure Container Registry cifra automáticamente las imágenes y otros artefactos que almacene. De forma predeterminada, Azure cifra automáticamente el contenido del Registro en reposo mediante claves administradas por el servicio. Mediante el uso de una clave administrada por el cliente, puede complementar el cifrado predeterminado con una capa de cifrado adicional.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "id": "A01.04", "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", "severity": "Medio", "subcategory": "Protección de datos", - "text": "Cifrar el registro con una clave administrada por el cliente" + "text": "Cifrar el registro con una clave administrada por el cliente", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Usar identidades administradas para proteger el acceso ACRPull/Push RBAC desde aplicaciones cliente", + "description": "Uso de identidades administradas para proteger el acceso ACRPull/Push RBAC desde aplicaciones cliente", "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "Alto", - "subcategory": "Identidad y control de acceso", - "text": "Usar identidades administradas para conectarse en lugar de entidades de servicio" + "subcategory": "Control de identidad y acceso", + "text": "Uso de identidades administradas para conectarse en lugar de entidades de servicio", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "La cuenta de administrador local está deshabilitada de forma predeterminada y no debe habilitarse. En su lugar, use métodos de acceso basados en token o RBAC", + "description": "La cuenta de administrador local está deshabilitada de forma predeterminada y no debe estar habilitada. En su lugar, use métodos de acceso basados en token o RBAC", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "Alto", - "subcategory": "Identidad y control de acceso", - "text": "Deshabilitar la autenticación local para el acceso al plano de administración" + "subcategory": "Control de identidad y acceso", + "text": "Deshabilitación de la autenticación local para el acceso al plano de administración", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Deshabilitar la cuenta de administrador y asignar roles RBAC a las entidades de seguridad para las operaciones de extracción/inserción de ACR", + "description": "Deshabilite la cuenta de administrador y asigne roles de RBAC a las entidades de seguridad para las operaciones de extracción/inserción de ACR", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", "severity": "Alto", - "subcategory": "Identidad y control de acceso", - "text": "Asigne roles RBAC de AcrPull y AcrPush en lugar de otorgar acceso administrativo a las entidades de identidad" + "subcategory": "Control de identidad y acceso", + "text": "Asigne roles RBAC AcrPull y AcrPush en lugar de conceder acceso administrativo a las entidades de identidad", + "waf": "Seguridad" }, { "category": "Seguridad", "description": "Deshabilitar el acceso anónimo de extracción/inserción", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", "severity": "Medio", - "subcategory": "Identidad y control de acceso", - "text": "Deshabilitar el acceso de extracción anónimo" + "subcategory": "Control de identidad y acceso", + "text": "Deshabilitar el acceso de extracción anónimo", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "La autenticación de token no admite la asignación a una entidad de seguridad de AAD. Cualquier token proporcionado puede ser utilizado por cualquier persona que pueda acceder al token.", + "description": "La autenticación de token no admite la asignación a una entidad de seguridad de AAD. Los tokens proporcionados pueden ser utilizados por cualquier persona que pueda acceder al token", "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", "severity": "Alto", - "subcategory": "Identidad y control de acceso", - "text": "Deshabilitar tokens de acceso con ámbito de repositorio" + "subcategory": "Control de identidad y acceso", + "text": "Deshabilitación de tokens de acceso con ámbito de repositorio", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Implementar imágenes de contenedor en un ACR detrás de un punto de conexión privado dentro de una red de confianza", + "description": "Implementación de imágenes de contenedor en un ACR detrás de un punto de conexión privado dentro de una red de confianza", "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "service": "ACR", "severity": "Alto", - "subcategory": "Identidad y control de acceso", - "text": "Implementar imágenes desde un entorno de confianza" + "subcategory": "Control de identidad y acceso", + "text": "Implementación de imágenes desde un entorno de confianza", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Solo se pueden usar tokens con una audiencia ACR para la autenticación. Se utiliza al analizar directivas de acceso condicional para ACR", + "description": "Solo los tokens con una audiencia de ACR se pueden usar para la autenticación. Se usa al habilitar directivas de acceso condicional para ACR", "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", "severity": "Medio", - "subcategory": "Identidad y control de acceso", - "text": "Deshabilitar tokens de audiencia de Azure ARM para la autenticación" + "subcategory": "Control de identidad y acceso", + "text": "Deshabilitación de tokens de audiencia de Azure ARM para la autenticación", + "waf": "Seguridad" }, { "category": "Seguridad", "description": "Configure una configuración de diagnóstico para enviar 'repositoryEvents' y 'LoginEvents' a Log Analytics como destino central para el registro y la supervisión. Esto le permite supervisar la actividad del plano de control en el propio recurso ACR.", "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", "severity": "Medio", - "subcategory": "Registro y supervisión", - "text": "Habilitar el registro de diagnósticos" + "subcategory": "Registro y monitoreo", + "text": "Habilitación del registro de diagnósticos", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "El servicio admite la deshabilitación del acceso a la red pública mediante el uso de la regla de filtrado de ACL de IP de nivel de servicio (no NSG o Azure Firewall) o mediante un conmutador de alternancia \"Deshabilitar acceso a redes públicas\"", + "description": "El servicio admite la deshabilitación del acceso a la red pública mediante la regla de filtrado de ACL de IP de nivel de servicio (no NSG ni Azure Firewall) o mediante un conmutador de alternancia \"Deshabilitar el acceso a la red pública\"", "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", "severity": "Medio", - "subcategory": "Seguridad de red", - "text": "Controle el acceso a la red entrante con Private Link" + "subcategory": "Seguridad de la red", + "text": "Controle el acceso a la red entrante con Private Link", + "waf": "Seguridad" }, { "category": "Seguridad", "description": "Deshabilitar el acceso a la red pública si el acceso a la red entrante está protegido mediante Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", "severity": "Medio", - "subcategory": "Seguridad de red", - "text": "Deshabilitar el acceso a la red pública" + "subcategory": "Seguridad de la red", + "text": "Deshabilitar el acceso a la red pública", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Solo la SKU Premium de ACR admite el acceso a Private Link", + "description": "Solo la SKU ACR Premium admite el acceso a Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", "severity": "Medio", - "subcategory": "Seguridad de red", - "text": "Use una SKU de Azure Container Registry que admita Private Link (SKU Premium)" + "subcategory": "Seguridad de la red", + "text": "Uso de una SKU de Azure Container Registry que admita Private Link (SKU Premium)", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Azure Defender para contenedores o el servicio equivalente se debe usar para examinar imágenes de contenedor en busca de vulnerabilidades", + "description": "Azure Defender para contenedores o un servicio equivalente debe usarse para examinar las imágenes de contenedor en busca de vulnerabilidades", "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", "severity": "Bajo", - "subcategory": "Seguridad de red", - "text": "Habilitar Defender for Containers para examinar Azure Container Registry en busca de vulnerabilidades" + "subcategory": "Seguridad de la red", + "text": "Habilitación de Defender para contenedores para examinar Azure Container Registry en busca de vulnerabilidades", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Implemente código de confianza validado y analizado en busca de vulnerabilidades de acuerdo con las prácticas de DevSecOps.", + "description": "Implemente código de confianza que se validó y analizó en busca de vulnerabilidades de acuerdo con las prácticas de DevSecOps.", "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "service": "ACR", "severity": "Medio", "subcategory": "Gestión de vulnerabilidades", - "text": "Implementar imágenes de contenedor validadas" + "text": "Implementación de imágenes de contenedor validadas", + "waf": "Seguridad" }, { "category": "Seguridad", - "description": "Utilice las últimas versiones de plataformas, lenguajes de programación, protocolos y marcos compatibles.", + "description": "Utilice las versiones más recientes de las plataformas, lenguajes de programación, protocolos y marcos compatibles.", "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", + "service": "ACR", "severity": "Alto", "subcategory": "Gestión de vulnerabilidades", - "text": "Utilice plataformas, lenguajes, protocolos y marcos actualizados" + "text": "Utilice plataformas, lenguajes, protocolos y marcos actualizados", + "waf": "Seguridad" } ], "metadata": { - "name": "Azure Container Registry Security Review" + "name": "Azure Container Registry Security Review", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "security" }, "severities": [ { @@ -189,7 +283,7 @@ "name": "Abrir" }, { - "description": "Esta comprobación se ha comprobado y no hay más elementos de acción asociados a ella", + "description": "Esta comprobación se ha verificado y no hay más elementos de acción asociados a ella", "name": "Cumplido" }, { @@ -200,5 +294,30 @@ "description": "No es necesario", "name": "No es necesario" } + ], + "waf": [ + { + "name": "Fiabilidad" + }, + { + "name": "Seguridad" + }, + { + "name": "Costar" + }, + { + "name": "Operaciones" + }, + { + "name": "Rendimiento" + } + ], + "yesno": [ + { + "name": "Sí" + }, + { + "name": "No" + } ] } \ No newline at end of file diff --git a/checklists/acr_checklist.ja.json b/checklists/acr_checklist.ja.json index 6aa7540b..a1ce4cd6 100644 --- a/checklists/acr_checklist.ja.json +++ b/checklists/acr_checklist.ja.json @@ -2,171 +2,265 @@ "categories": [ { "name": "安全" + }, + { + "name": "ネットワーク トポロジと接続性" + }, + { + "name": "運用管理" + }, + { + "name": "プラットフォームの自動化" + }, + { + "name": "安全" + }, + { + "name": "台帳" + }, + { + "name": "伐採" + }, + { + "name": "ネットワーキング" + }, + { + "name": "データの検出と分類" + }, + { + "name": "データマスキング" + }, + { + "name": "コード" } ], "items": [ { "category": "安全", - "description": "データの流出を防ぐために画像のエクスポートを無効にします。これにより、別の ACR インスタンスへのイメージのインポートが防止されることに注意してください。", + "description": "データの流出を防ぐために、画像のエクスポートを無効にします。これにより、別の ACR インスタンスに画像がインポートされなくなることに注意してください。", "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "id": "A01.01", "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", "severity": "高い", "subcategory": "データ保護", - "text": "Azure コンテナー レジストリ イメージのエクスポートを無効にする" + "text": "Azure Container Registry イメージのエクスポートを無効にする", + "waf": "安全" }, { "category": "安全", - "description": "監査コンプライアンスの可視性を有効にするには、Azur eContainer レジストリの Azure Policy を有効にします。", + "description": "Azure Container Registry の Azure Policy を有効にすることで、監査コンプライアンスの可視性を有効にする", "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "id": "A01.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", "severity": "高い", "subcategory": "データ保護", - "text": "Azure コンテナー レジストリの Azure ポリシーを有効にする" + "text": "Azure Container Registry の Azure ポリシーを有効にする", + "waf": "安全" }, { "category": "安全", - "description": "Azure Key Vault (AKV) は、コンテナー イメージやその他の成果物に署名して検証するために、AKV プラグイン (azure-kv) という表記法で使用できる署名キーを格納するために使用されます。Azure コンテナー レジストリ (ACR) を使用すると、az または oras CLI コマンドを使用してこれらの署名をアタッチできます。", + "description": "Azure Key Vault (AKV) は、AKV プラグイン (azure-kv) という表記を使用して、コンテナー イメージやその他の成果物に署名および検証できる署名キーを格納するために使用されます。Azure Container Registry (ACR) では、これらの署名を az?or?oras?CLI コマンド。", "guid": "d345293c-7639-4637-a551-c5c04e401955", + "id": "A01.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", "severity": "高い", "subcategory": "データ保護", - "text": "表記法を使用したコンテナーの署名と検証 (公証人 v2)" + "text": "表記法によるコンテナの署名と検証(Notary v2)", + "waf": "安全" }, { "category": "安全", - "description": "Azure コンテナー レジストリでは、格納するイメージやその他の成果物が自動的に暗号化されます。既定では、Azure はサービス マネージド キーを使用して保存時のレジストリ コンテンツを自動的に暗号化します。カスタマー マネージド キーを使用すると、既定の暗号化を追加の暗号化レイヤーで補完できます。", + "description": "Azure Container Registry は、格納するイメージやその他の成果物を自動的に暗号化します。既定では、Azure はサービス マネージド キーを使用して、保存中のレジストリ コンテンツを自動的に暗号化します。カスタマー管理のキーを使用すると、デフォルトの暗号化を追加の暗号化レイヤーで補完できます。", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "id": "A01.04", "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", "severity": "中程度", "subcategory": "データ保護", - "text": "カスタマー マネージド キーを使用したレジストリの暗号化" + "text": "カスタマー マネージド キーを使用してレジストリを暗号化する", + "waf": "安全" }, { "category": "安全", - "description": "マネージド ID を使用して、クライアント アプリケーションからの ACRPull/プッシュ RBAC アクセスをセキュリティで保護する", + "description": "マネージド ID を使用して、クライアント アプリケーションからの ACRPull/Push RBAC アクセスをセキュリティで保護する", "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "高い", "subcategory": "ID とアクセス制御", - "text": "サービス プリンシパルの代わりにマネージド ID を使用して接続する" + "text": "サービス プリンシパルの代わりにマネージド ID を使用して接続する", + "waf": "安全" }, { "category": "安全", - "description": "ローカル管理者アカウントは既定で無効になっているため、有効にしないでください。代わりにトークンまたは RBAC ベースのアクセス方法を使用する", + "description": "ローカルの管理者アカウントはデフォルトで無効になっているため、有効にしないでください。代わりに、トークンまたは RBAC ベースのアクセス方法を使用してください", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "高い", "subcategory": "ID とアクセス制御", - "text": "管理プレーンアクセスのローカル認証を無効にする" + "text": "管理プレーン アクセスのローカル認証を無効にする", + "waf": "安全" }, { "category": "安全", "description": "管理者アカウントを無効にし、ACR プル/プッシュ操作のプリンシパルに RBAC ロールを割り当てる", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", "severity": "高い", "subcategory": "ID とアクセス制御", - "text": "ID プリンシパルに管理アクセス権を付与するのではなく、AcrPull & AcrPush RBAC ロールを割り当てる" + "text": "ID プリンシパルに管理アクセス権を付与するのではなく、AcrPull および AcrPush RBAC ロールを割り当てる", + "waf": "安全" }, { "category": "安全", - "description": "匿名プル/プッシュアクセスを無効にする", + "description": "匿名プル/プッシュ アクセスを無効にする", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", "severity": "中程度", "subcategory": "ID とアクセス制御", - "text": "匿名プルアクセスを無効にする" + "text": "匿名プル アクセスを無効にする", + "waf": "安全" }, { "category": "安全", - "description": "トークン認証では、AAD プリンシパルへの割り当てはサポートされていません。提供されたトークンは、トークンにアクセスできるすべてのユーザーが使用できます", + "description": "トークン認証では、AAD プリンシパルへの割り当てはサポートされていません。提供されたトークンは、トークンにアクセスできる人なら誰でも使用できます", "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", "severity": "高い", "subcategory": "ID とアクセス制御", - "text": "リポジトリスコープのアクセストークンを無効にする" + "text": "リポジトリ スコープのアクセス トークンを無効にする", + "waf": "安全" }, { "category": "安全", "description": "信頼されたネットワーク内のプライベート エンドポイントの背後にある ACR にコンテナー イメージをデプロイする", "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "service": "ACR", "severity": "高い", "subcategory": "ID とアクセス制御", - "text": "信頼できる環境からイメージを展開する" + "text": "信頼できる環境からのイメージのデプロイ", + "waf": "安全" }, { "category": "安全", - "description": "ACR 対象ユーザーを持つトークンのみを認証に使用できます。ACR の条件付きアクセス ポリシーを分析するときに使用", + "description": "認証に使用できるのは、ACR 対象ユーザーを持つトークンのみです。ACR の条件付きアクセス ポリシーを有効にするときに使用されます", "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", "severity": "中程度", "subcategory": "ID とアクセス制御", - "text": "認証のために Azure ARM 対象ユーザー トークンを無効にする" + "text": "認証のために Azure ARM 対象ユーザー トークンを無効にする", + "waf": "安全" }, { "category": "安全", - "description": "ログ記録と監視の中心的な宛先として Log Analytics に \"リポジトリ イベント\" と \"ログイン イベント\" を送信するように診断設定を設定します。これにより、ACR リソース自体のコントロール プレーン アクティビティを監視できます。", + "description": "'repositoryEvents' と 'LoginEvents' をログ記録と監視の中心的な宛先として Log Analytics に送信するように診断設定を設定します。これにより、ACR リソース自体のコントロール プレーン アクティビティを監視できます。", "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", "severity": "中程度", - "subcategory": "ログ記録と監視", - "text": "診断ログを有効にする" + "subcategory": "ロギングとモニタリング", + "text": "診断ログを有効にする", + "waf": "安全" }, { "category": "安全", - "description": "サービスでは、サービス レベルの IP ACL フィルター規則 (NSG または Azure Firewall ではない) を使用するか、[パブリック ネットワーク アクセスを無効にする] トグル スイッチを使用して、パブリック ネットワーク アクセスを無効にすることができます。", + "description": "サービスでは、サービス レベルの IP ACL フィルタリング規則 (NSG や Azure Firewall ではない) を使用するか、\"パブリック ネットワーク アクセスを無効にする\" トグル スイッチを使用して、パブリック ネットワーク アクセスを無効にすることがサポートされています", "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", "severity": "中程度", "subcategory": "ネットワークセキュリティ", - "text": "プライベート リンクを使用した受信ネットワーク アクセスの制御" + "text": "Private Link を使用して受信ネットワーク アクセスを制御する", + "waf": "安全" }, { "category": "安全", - "description": "受信ネットワーク アクセスが Private Link を使用してセキュリティで保護されている場合は、パブリック ネットワーク アクセスを無効にする", + "description": "Private Link を使用して受信ネットワーク アクセスがセキュリティで保護されている場合は、パブリック ネットワーク アクセスを無効にする", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", "severity": "中程度", "subcategory": "ネットワークセキュリティ", - "text": "パブリックネットワークアクセスを無効にする" + "text": "パブリックネットワークアクセスを無効にする", + "waf": "安全" }, { "category": "安全", - "description": "ACR プレミアム SKU のみがプライベート リンク アクセスをサポートします", + "description": "ACR Premium SKU のみが Private Link アクセスをサポートします", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", "severity": "中程度", "subcategory": "ネットワークセキュリティ", - "text": "プライベート リンク (Premium SKU) をサポートする Azure コンテナー レジストリ SKU を使用する" + "text": "Private Link をサポートする Azure Container Registry SKU を使用する (Premium SKU)", + "waf": "安全" }, { "category": "安全", - "description": "コンテナーまたは同等のサービス用の Azure Defender を使用して、コンテナー イメージの脆弱性をスキャンする必要があります", + "description": "Azure Defender for containers または同等のサービスを使用して、コンテナー イメージの脆弱性をスキャンする必要があります", "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", "severity": "低い", "subcategory": "ネットワークセキュリティ", - "text": "コンテナーの Defender が Azure コンテナー レジストリの脆弱性をスキャンできるようにする" + "text": "Defender for Containers で Azure Container Registry の脆弱性をスキャンできるようにする", + "waf": "安全" }, { "category": "安全", - "description": "DevSecOps プラクティスに従って脆弱性が検証およびスキャンされた信頼できるコードをデプロイします。", + "description": "DevSecOps のプラクティスに従って脆弱性が検証およびスキャンされた信頼できるコードをデプロイします。", "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "service": "ACR", "severity": "中程度", "subcategory": "脆弱性管理", - "text": "検証済みのコンテナー イメージをデプロイする" + "text": "検証済みのコンテナイメージをデプロイする", + "waf": "安全" }, { "category": "安全", - "description": "サポートされているプラットフォーム、プログラミング言語、プロトコル、およびフレームワークの最新バージョンを使用します。", + "description": "サポートされているプラットフォーム、プログラミング言語、プロトコル、およびフレームワークの最新バージョンを使用してください。", "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", + "service": "ACR", "severity": "高い", "subcategory": "脆弱性管理", - "text": "最新のプラットフォーム、言語、プロトコル、フレームワークを使用する" + "text": "最新のプラットフォーム、言語、プロトコル、フレームワークを使用", + "waf": "安全" } ], "metadata": { - "name": "Azure Container Registry Security Review" + "name": "Azure Container Registry Security Review", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "security" }, "severities": [ { @@ -181,24 +275,49 @@ ], "status": [ { - "description": "このチェックはまだ確認されていません", + "description": "このチェックはまだ見ていません", "name": "未確認" }, { - "description": "このチェックに関連付けられているアクションアイテムがあります", + "description": "このチェックにはアクションアイテムが関連付けられています", "name": "開ける" }, { - "description": "このチェックは検証済みであり、それ以上のアクションアイテムは関連付けられていません", + "description": "このチェックは検証済みであり、これ以上のアクション アイテムは関連付けられていません", "name": "達成" }, { - "description": "現在のデザインには適用できません", + "description": "現在のデザインには適用されません", "name": "該当なし" }, { "description": "必須ではありません", "name": "必須ではありません" } + ], + "waf": [ + { + "name": "確実" + }, + { + "name": "安全" + }, + { + "name": "費用" + }, + { + "name": "オペレーションズ" + }, + { + "name": "パフォーマンス" + } + ], + "yesno": [ + { + "name": "はい" + }, + { + "name": "いいえ" + } ] } \ No newline at end of file diff --git a/checklists/acr_checklist.ko.json b/checklists/acr_checklist.ko.json index 7ef5b9b1..e0c7f9ba 100644 --- a/checklists/acr_checklist.ko.json +++ b/checklists/acr_checklist.ko.json @@ -2,6 +2,36 @@ "categories": [ { "name": "안전" + }, + { + "name": "네트워크 토폴로지 및 연결" + }, + { + "name": "운영 관리" + }, + { + "name": "플랫폼 자동화" + }, + { + "name": "안전" + }, + { + "name": "원장" + }, + { + "name": "로깅" + }, + { + "name": "네트워킹" + }, + { + "name": "데이터 검색 및 분류" + }, + { + "name": "데이터 마스킹" + }, + { + "name": "코드" } ], "items": [ @@ -9,164 +39,228 @@ "category": "안전", "description": "데이터 반출을 방지하기 위해 이미지 내보내기를 비활성화합니다. 이렇게 하면 이미지를 다른 ACR 인스턴스로 가져올 수 없습니다.", "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "id": "A01.01", "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", "severity": "높다", "subcategory": "데이터 보호", - "text": "Azure 컨테이너 레지스트리 이미지 내보내기 사용 안 함" + "text": "Azure Container Registry 이미지 내보내기 사용 안 함", + "waf": "안전" }, { "category": "안전", - "description": "Azure용 Azure Policy를 사용하도록 설정하여 감사 규정 준수 가시성 사용", + "description": "Azure Container Registry에 대해 Azure Policy를 사용하도록 설정하여 감사 규정 준수 가시성 사용Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "id": "A01.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", "severity": "높다", "subcategory": "데이터 보호", - "text": "Azure 컨테이너 레지스트리에 대한 Azure 정책 사용" + "text": "Azure Container Registry에 대한 Azure 정책 사용", + "waf": "안전" }, { "category": "안전", - "description": "AKV(Azure 키 자격 증명 모음)는 컨테이너 이미지 및 기타 아티팩트에 서명하고 확인하기 위해 AKV 플러그 인(azure-kv) 표기법으로 표기하여 사용할 수 있는 서명 키를 저장하는 데 사용됩니다. ACR(Azure 컨테이너 레지스트리)을 사용하면 az 또는 oras CLI 명령을 사용하여 이러한 서명을 연결할 수 있습니다.", + "description": "AKV(Azure Key Vault)는 컨테이너 이미지 및 기타 아티팩트에 서명하고 확인하기 위해 AKV 플러그 인(azure-kv) 표기법과 함께 사용할 수 있는 서명 키를 저장하는 데 사용됩니다. ACR(Azure Container Registry)을 사용하면 ?az?또는?oras? CLI 명령.", "guid": "d345293c-7639-4637-a551-c5c04e401955", + "id": "A01.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", "severity": "높다", "subcategory": "데이터 보호", - "text": "표기법으로 컨테이너 서명 및 확인(Notary v2)" + "text": "표기법을 사용하여 컨테이너 서명 및 확인(Notary v2)", + "waf": "안전" }, { "category": "안전", - "description": "Azure 컨테이너 레지스트리는 사용자가 저장하는 이미지 및 기타 아티팩트를 자동으로 암호화합니다. 기본적으로 Azure는 서비스 관리형 키를 사용하여 미사용 레지스트리 콘텐츠를 자동으로 암호화합니다. 고객 관리형 키를 사용하면 추가 암호화 계층으로 기본 암호화를 보완할 수 있습니다.", + "description": "Azure Container Registry는 저장하는 이미지 및 기타 아티팩트를 자동으로 암호화합니다. 기본적으로 Azure는 서비스 관리형 키를 사용하여 미사용 레지스트리 콘텐츠를 자동으로 암호화합니다. 고객 관리형 키를 사용하면 추가 암호화 계층으로 기본 암호화를 보완할 수 있습니다.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "id": "A01.04", "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", "severity": "보통", "subcategory": "데이터 보호", - "text": "고객 관리형 키로 레지스트리 암호화" + "text": "고객 관리형 키로 레지스트리 암호화Encrypt registry with a customer managed key", + "waf": "안전" }, { "category": "안전", - "description": "관리 ID를 사용하여 클라이언트 애플리케이션에서 ACRPull/푸시 RBAC 액세스 보호", + "description": "관리 ID를 사용하여 클라이언트 애플리케이션에서 ACRPull/Push RBAC 액세스 보호", "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "높다", - "subcategory": "ID 및 액세스 제어", - "text": "서비스 주체 대신 관리 ID를 사용하여 연결" + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "서비스 주체 대신 관리 ID를 사용하여 연결", + "waf": "안전" }, { "category": "안전", - "description": "로컬 관리자 계정은 기본적으로 사용하지 않도록 설정되어 있으며 사용하도록 설정해서는 안 됩니다. 대신 토큰 또는 RBAC 기반 액세스 방법을 사용하십시오.", + "description": "로컬 관리자 계정은 기본적으로 사용하지 않도록 설정되어 있으며 사용하도록 설정해서는 안 됩니다. 대신 토큰 또는 RBAC 기반 액세스 방법을 사용합니다.", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "높다", - "subcategory": "ID 및 액세스 제어", - "text": "관리부 액세스에 대한 로컬 인증 비활성화" + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "관리부 액세스에 대한 로컬 인증 사용 안 함Disable local authentication for management plane access", + "waf": "안전" }, { "category": "안전", - "description": "관리자 계정을 사용하지 않도록 설정하고 ACR 끌어오기/밀어넣기 작업을 위해 보안 주체에 RBAC 역할 할당", + "description": "관리자 계정을 사용하지 않도록 설정하고 ACR 끌어오기/푸시 작업을 위해 보안 주체에 RBAC 역할을 할당합니다.", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", "severity": "높다", - "subcategory": "ID 및 액세스 제어", - "text": "ID 주체에 대한 관리 액세스 권한을 부여하는 대신 AcrPull & AcrPush RBAC 역할을 할당합니다." + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "ID 주체에 대한 관리 액세스 권한을 부여하는 대신 AcrPull 및 AcrPush RBAC 역할을 할당합니다.", + "waf": "안전" }, { "category": "안전", - "description": "익명 풀/푸시 액세스 비활성화", + "description": "익명 끌어오기/밀어넣기 액세스 사용 안 함Disable anonymous pull/push access", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", "severity": "보통", - "subcategory": "ID 및 액세스 제어", - "text": "익명 끌어오기 액세스 사용 안 함" + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "익명 끌어오기 액세스 사용 안 함Disable Anonymous pull access", + "waf": "안전" }, { "category": "안전", - "description": "토큰 인증은 AAD 보안 주체에 대한 할당을 지원하지 않습니다. 제공된 모든 토큰은 토큰에 액세스할 수 있는 모든 사용자가 사용할 수 있습니다.", + "description": "토큰 인증은 AAD 보안 주체에 대한 할당을 지원하지 않습니다. 제공된 모든 토큰은 토큰에 액세스할 수 있는 모든 사람이 사용할 수 있습니다", "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", "severity": "높다", - "subcategory": "ID 및 액세스 제어", - "text": "리포지토리 범위 액세스 토큰 사용 안 함" + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "리포지토리 범위 액세스 토큰 사용 안 함Disable repository-scoped access tokens", + "waf": "안전" }, { "category": "안전", - "description": "신뢰할 수 있는 네트워크 내의 프라이빗 엔드포인트 뒤에 있는 ACR에 컨테이너 이미지 배포", + "description": "신뢰할 수 있는 네트워크 내의 프라이빗 엔드포인트 뒤에 있는 ACR에 컨테이너 이미지 배포Deploy container images to an ACR behind a Private endpoint within a trusted network", "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "service": "ACR", "severity": "높다", - "subcategory": "ID 및 액세스 제어", - "text": "신뢰할 수 있는 환경에서 이미지 배포" + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "신뢰할 수 있는 환경에서 이미지 배포", + "waf": "안전" }, { "category": "안전", - "description": "ACR 대상 그룹이 있는 토큰만 인증에 사용할 수 있습니다. ACR에 대한 조건부 액세스 정책을 분석할 때 사용됩니다.", + "description": "ACR 대상이 있는 토큰만 인증에 사용할 수 있습니다. ACR에 대한 조건부 액세스 정책을 사용하도록 설정할 때 사용됩니다.", "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", "severity": "보통", - "subcategory": "ID 및 액세스 제어", - "text": "인증을 위해 Azure ARM 대상 토큰을 사용하지 않도록 설정" + "subcategory": "ID 및 액세스 제어Identity and Access Control", + "text": "인증을 위해 Azure ARM 대상 토큰 사용 안 함", + "waf": "안전" }, { "category": "안전", - "description": "'repositoryEvents' 및 'LoginEvents'를 로깅 및 모니터링을 위한 중앙 대상으로 Log Analytics에 보내도록 진단 설정을 설정합니다. 이렇게 하면 ACR 리소스 자체에서 컨트롤 플레인 작업을 모니터링할 수 있습니다.", + "description": "'repositoryEvents' 및 'LoginEvents'를 로깅 및 모니터링의 중앙 대상으로 Log Analytics에 보내도록 진단 설정을 지정합니다. 이렇게 하면 ACR 리소스 자체에 대한 컨트롤 플레인 작업을 모니터링할 수 있습니다.", "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", "severity": "보통", "subcategory": "로깅 및 모니터링", - "text": "진단 로깅 사용" + "text": "진단 로깅 사용Enable diagnostics logging", + "waf": "안전" }, { "category": "안전", - "description": "서비스는 서비스 수준 IP ACL 필터링 규칙(NSG 또는 Azure Firewall이 아님)을 사용하거나 '공용 네트워크 액세스 사용 안 함' 토글 스위치를 사용하여 공용 네트워크 액세스를 사용하지 않도록 지원합니다.", + "description": "서비스는 서비스 수준 IP ACL 필터링 규칙(NSG 또는 Azure Firewall 아님)을 사용하거나 '공용 네트워크 액세스 사용 안 함' 토글 스위치를 사용하여 공용 네트워크 액세스를 사용하지 않도록 지원합니다", "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", "severity": "보통", "subcategory": "네트워크 보안", - "text": "Private Link로 인바운드 네트워크 액세스 제어" + "text": "Private Link를 사용하여 인바운드 네트워크 액세스 제어", + "waf": "안전" }, { "category": "안전", - "description": "Private Link를 사용하여 인바운드 네트워크 액세스가 보호되는 경우 공용 네트워크 액세스 비활성화", + "description": "Private Link를 사용하여 인바운드 네트워크 액세스가 보호되는 경우 공용 네트워크 액세스 사용 안 함", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", "severity": "보통", "subcategory": "네트워크 보안", - "text": "공용 네트워크 액세스 사용 안 함" + "text": "공용 네트워크 액세스 사용 안 함", + "waf": "안전" }, { "category": "안전", - "description": "ACR 프리미엄 SKU만 프라이빗 링크 액세스를 지원합니다.", + "description": "ACR Premium SKU만 Private Link 액세스를 지원합니다.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", "severity": "보통", "subcategory": "네트워크 보안", - "text": "프라이빗 링크(프리미엄 SKU)를 지원하는 Azure 컨테이너 레지스트리 SKU 사용" + "text": "Private Link(프리미엄 SKU)를 지원하는 Azure Container Registry SKU 사용", + "waf": "안전" }, { "category": "안전", - "description": "컨테이너용 Azure Defender 또는 동등한 서비스를 사용하여 컨테이너 이미지에서 취약성을 검사해야 합니다.", + "description": "컨테이너용 Azure Defender 또는 동등한 서비스를 사용하여 컨테이너 이미지의 취약성을 검사해야 합니다.", "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", "severity": "낮다", "subcategory": "네트워크 보안", - "text": "컨테이너용 Defender를 사용하도록 설정하여 Azure 컨테이너 레지스트리에서 취약성을 검사합니다." + "text": "컨테이너용 Defender를 사용하여 Azure Container Registry에서 취약성을 검사하도록 설정", + "waf": "안전" }, { "category": "안전", - "description": "DevSecOps 사례에 따라 취약성에 대해 유효성을 검사하고 검사한 신뢰할 수 있는 코드를 배포합니다.", + "description": "DevSecOps 사례에 따라 취약성을 검증하고 스캔한 신뢰할 수 있는 코드를 배포합니다.", "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "service": "ACR", "severity": "보통", "subcategory": "취약성 관리", - "text": "검증된 컨테이너 이미지 배포" + "text": "유효성이 검사된 컨테이너 이미지 배포", + "waf": "안전" }, { "category": "안전", "description": "지원되는 플랫폼, 프로그래밍 언어, 프로토콜 및 프레임워크의 최신 버전을 사용합니다.", "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", + "service": "ACR", "severity": "높다", "subcategory": "취약성 관리", - "text": "최신 플랫폼, 언어, 프로토콜 및 프레임워크 사용" + "text": "최신 플랫폼, 언어, 프로토콜 및 프레임워크 사용", + "waf": "안전" } ], "metadata": { - "name": "Azure Container Registry Security Review" + "name": "Azure Container Registry Security Review", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "security" }, "severities": [ { @@ -181,24 +275,49 @@ ], "status": [ { - "description": "이 검사는 아직 검토되지 않았습니다.", + "description": "이 검사는 아직 검토되지 않았습니다", "name": "확인되지 않음" }, { - "description": "이 검사와 연결된 작업 항목이 있습니다.", + "description": "이 검사와 연관된 작업 항목이 있습니다", "name": "열다" }, { - "description": "이 검사가 확인되었으며 연결된 추가 작업 항목이 없습니다.", + "description": "이 검사는 확인되었으며 이와 관련된 추가 작업 항목이 없습니다", "name": "성취" }, { - "description": "현재 디자인에는 적용되지 않음", + "description": "현재 설계에는 적용되지 않습니다.", "name": "해당 없음" }, { - "description": "필요하지 않음", - "name": "필요하지 않음" + "description": "필요 없음", + "name": "필요 없음" + } + ], + "waf": [ + { + "name": "신뢰도" + }, + { + "name": "안전" + }, + { + "name": "비용" + }, + { + "name": "작업" + }, + { + "name": "공연" + } + ], + "yesno": [ + { + "name": "예" + }, + { + "name": "아니요" } ] } \ No newline at end of file diff --git a/checklists/acr_checklist.pt.json b/checklists/acr_checklist.pt.json index be6317eb..dff9292a 100644 --- a/checklists/acr_checklist.pt.json +++ b/checklists/acr_checklist.pt.json @@ -2,171 +2,265 @@ "categories": [ { "name": "Segurança" + }, + { + "name": "Topologia e conectividade de rede" + }, + { + "name": "Gestão de operações" + }, + { + "name": "Automação de plataforma" + }, + { + "name": "Segurança" + }, + { + "name": "Livro-razão" + }, + { + "name": "Log" + }, + { + "name": "Rede" + }, + { + "name": "Descoberta e classificação de dados" + }, + { + "name": "Mascaramento de dados" + }, + { + "name": "Código" } ], "items": [ { "category": "Segurança", - "description": "Desative a exportação de imagens para impedir a exfiltração de dados. Observe que isso impedirá a importação de imagens para outra instância ACR.", + "description": "Desative a exportação de imagens para evitar a exfiltração de dados. Observe que isso impedirá a importação de imagens para outra instância do ACR.", "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "id": "A01.01", "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", "severity": "Alto", - "subcategory": "Proteção de Dados", - "text": "Desabilitar a exportação de imagem do Registro de Contêiner do Azure" + "subcategory": "Proteção de dados", + "text": "Desabilitar a exportação de imagem do Registro de Contêiner do Azure", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Habilite a visibilidade da conformidade de auditoria habilitando o Registro de eContainer da Política do Azure para Azur", + "description": "Habilite a visibilidade de conformidade de auditoria habilitando o Azure Policy para o Registro de Contêiner do Azure", "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "id": "A01.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", "severity": "Alto", - "subcategory": "Proteção de Dados", - "text": "Habilitar Políticas do Azure para o Registro de Contêiner do Azure" + "subcategory": "Proteção de dados", + "text": "Habilitar Políticas do Azure para o Registro de Contêiner do Azure", + "waf": "Segurança" }, { "category": "Segurança", - "description": "O Cofre da Chave do Azure (AKV) é usado para armazenar uma chave de assinatura que pode ser utilizada por notação com o plug-in AKV de notação (azure-kv) para assinar e verificar imagens de contêiner e outros artefatos. O ACR (Registro de Contêiner) do Azure permite que você anexe essas assinaturas usando os comandos da CLI az ou oras.", + "description": "O Azure Key Vault (AKV) é usado para armazenar uma chave de assinatura que pode ser utilizada por?notação?com o plug-in AKV de notação (azure-kv) para assinar e verificar imagens de contêiner e outros artefatos. O ACR (Registro de Contêiner do Azure) permite que você anexe essas assinaturas usando o?az?ou?oras? Comandos da CLI.", "guid": "d345293c-7639-4637-a551-c5c04e401955", + "id": "A01.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", "severity": "Alto", - "subcategory": "Proteção de Dados", - "text": "Assinar e verificar contêineres com notação (notário v2)" + "subcategory": "Proteção de dados", + "text": "Assinar e verificar contêineres com notação (Notary v2)", + "waf": "Segurança" }, { "category": "Segurança", - "description": "O Registro de Contêiner do Azure criptografa automaticamente imagens e outros artefatos que você armazena. Por padrão, o Azure criptografa automaticamente o conteúdo do Registro em repouso usando chaves gerenciadas por serviço. Usando uma chave gerenciada pelo cliente, você pode complementar a criptografia padrão com uma camada de criptografia adicional.", + "description": "O Registro de Contêiner do Azure criptografa automaticamente imagens e outros artefatos que você armazena. Por padrão, o Azure criptografa automaticamente o conteúdo do Registro em repouso usando chaves gerenciadas pelo serviço. Usando uma chave gerenciada pelo cliente, você pode complementar a criptografia padrão com uma camada de criptografia adicional.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "id": "A01.04", "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", "severity": "Média", - "subcategory": "Proteção de Dados", - "text": "Criptografar o registro com uma chave gerenciada pelo cliente" + "subcategory": "Proteção de dados", + "text": "Criptografar o registro com uma chave gerenciada pelo cliente", + "waf": "Segurança" }, { "category": "Segurança", "description": "Usar identidades gerenciadas para proteger o acesso RBAC ACRPull/Push de aplicativos cliente", "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "Alto", - "subcategory": "Controle de Identidade e Acesso", - "text": "Usar identidades gerenciadas para se conectar em vez de entidades de serviço" + "subcategory": "Controle de identidade e acesso", + "text": "Usar identidades gerenciadas para se conectar em vez de entidades de serviço", + "waf": "Segurança" }, { "category": "Segurança", - "description": "A conta de Administrador local está desabilitada por padrão e não deve ser habilitada. Em vez disso, use métodos de acesso baseados em Token ou RBAC", + "description": "A conta de administrador local está desabilitada por padrão e não deve ser habilitada. Em vez disso, use métodos de acesso baseados em token ou RBAC", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", "severity": "Alto", - "subcategory": "Controle de Identidade e Acesso", - "text": "Desabilitar a autenticação local para acesso ao plano de gerenciamento" + "subcategory": "Controle de identidade e acesso", + "text": "Desabilitar a autenticação local para acesso ao plano de gerenciamento", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Desabilitar a conta de Administrador e atribuir funções RBAC a entidades de segurança para operações de Pull/Push do ACR", + "description": "Desabilitar a conta de administrador e atribuir funções RBAC a entidades de segurança para operações de pull/push do ACR", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", "severity": "Alto", - "subcategory": "Controle de Identidade e Acesso", - "text": "Atribuir funções AcrPull e AcrPush RBAC em vez de conceder acesso administrativo a entidades de identidade" + "subcategory": "Controle de identidade e acesso", + "text": "Atribuir funções RBAC AcrPull e AcrPush em vez de conceder acesso administrativo a entidades de identidade", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Desativar o acesso anônimo pull/push", + "description": "Desabilitar acesso anônimo de pull/push", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", "severity": "Média", - "subcategory": "Controle de Identidade e Acesso", - "text": "Desabilitar o acesso pull anônimo" + "subcategory": "Controle de identidade e acesso", + "text": "Desabilitar o acesso pull anônimo", + "waf": "Segurança" }, { "category": "Segurança", - "description": "A autenticação de token não oferece suporte à atribuição a uma entidade de segurança do AAD. Quaisquer tokens fornecidos podem ser usados por qualquer pessoa que possa acessar o token", + "description": "A autenticação de token não dá suporte à atribuição a uma entidade de segurança do AAD. Quaisquer tokens fornecidos podem ser usados por qualquer pessoa que possa acessar o token", "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", "severity": "Alto", - "subcategory": "Controle de Identidade e Acesso", - "text": "Desabilitar tokens de acesso com escopo de repositório" + "subcategory": "Controle de identidade e acesso", + "text": "Desabilitar tokens de acesso no escopo do repositório", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Implantar imagens de contêiner em um ACR atrás de um ponto de extremidade privado em uma rede confiável", + "description": "Implantar imagens de contêiner em um ACR por trás de um ponto de extremidade privado em uma rede confiável", "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "service": "ACR", "severity": "Alto", - "subcategory": "Controle de Identidade e Acesso", - "text": "Implantar imagens de um ambiente confiável" + "subcategory": "Controle de identidade e acesso", + "text": "Implantar imagens de um ambiente confiável", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Somente tokens com uma audiência ACR podem ser usados para autenticação. Usado ao analisar políticas de acesso condicional para ACR", + "description": "Somente tokens com um público-alvo do ACR podem ser usados para autenticação. Usado ao habilitar políticas de acesso condicional para ACR", "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", "severity": "Média", - "subcategory": "Controle de Identidade e Acesso", - "text": "Desabilitar tokens de audiência do ARM do Azure para autenticação" + "subcategory": "Controle de identidade e acesso", + "text": "Desabilitar tokens de audiência do ARM do Azure para autenticação", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Configure uma configuração de diagnóstico para enviar 'repositoryEvents' e 'LoginEvents' para o Log Analytics como o destino central para registro em log e monitoramento. Isso permite que você monitore a atividade do plano de controle no próprio recurso ACR.", + "description": "Configure uma configuração de diagnóstico para enviar 'repositoryEvents' e 'LoginEvents' para o Log Analytics como o destino central para registro em log e monitoramento. Isso permite que você monitore a atividade do plano de controle no próprio recurso do ACR.", "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", "severity": "Média", - "subcategory": "Registro em log e monitoramento", - "text": "Habilitar o log de diagnóstico" + "subcategory": "Registro e monitoramento", + "text": "Habilitar o log de diagnóstico", + "waf": "Segurança" }, { "category": "Segurança", - "description": "O serviço dá suporte à desabilitação do acesso à rede pública usando a regra de filtragem de ACL IP de nível de serviço (não NSG ou Firewall do Azure) ou usando um botão de alternância 'Desabilitar Acesso à Rede Pública'", + "description": "O serviço dá suporte à desabilitação do acesso à rede pública usando a regra de filtragem de ACL IP no nível do serviço (não NSG ou Firewall do Azure) ou usando uma opção de alternância 'Desabilitar Acesso à Rede Pública'", "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", "severity": "Média", "subcategory": "Segurança de rede", - "text": "Controle o acesso à rede de entrada com o Private Link" + "text": "Controle o acesso à rede de entrada com Link Privado", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Desabilitar o acesso à rede pública se o acesso à rede de entrada estiver protegido usando o Link Privado", + "description": "Desative o acesso à rede pública se o acesso à rede de entrada for protegido usando o Link Privado", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", "severity": "Média", "subcategory": "Segurança de rede", - "text": "Desabilitar o acesso à Rede Pública" + "text": "Desabilitar o acesso à rede pública", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Apenas o ACR Premium SKU suporta acesso a Link Privado", + "description": "Somente o SKU do ACR Premium dá suporte ao acesso ao Link Privado", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", "severity": "Média", "subcategory": "Segurança de rede", - "text": "Usar uma SKU do Registro de Contêiner do Azure que dá suporte ao Private Link (SKU Premium)" + "text": "Usar um SKU do Registro de Contêiner do Azure que dá suporte ao Link Privado (SKU Premium)", + "waf": "Segurança" }, { "category": "Segurança", - "description": "O Azure Defender para contêineres ou serviço equivalente deve ser usado para verificar imagens de contêiner em busca de vulnerabilidades", + "description": "O Azure Defender para contêineres ou serviço equivalente deve ser usado para verificar se há vulnerabilidades em imagens de contêiner", "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", "severity": "Baixo", "subcategory": "Segurança de rede", - "text": "Habilitar o Defender for Containers para verificar o Registro de Contêiner do Azure em busca de vulnerabilidades" + "text": "Habilitar o Defender para Contêineres para verificar se há vulnerabilidades no Registro de Contêiner do Azure", + "waf": "Segurança" }, { "category": "Segurança", "description": "Implante código confiável que foi validado e verificado em busca de vulnerabilidades de acordo com as práticas de DevSecOps.", "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "service": "ACR", "severity": "Média", "subcategory": "Gerenciamento de vulnerabilidades", - "text": "Implantar imagens de contêiner validadas" + "text": "Implantar imagens de contêiner validadas", + "waf": "Segurança" }, { "category": "Segurança", - "description": "Use as versões mais recentes de plataformas, linguagens de programação, protocolos e estruturas suportados.", + "description": "Use as versões mais recentes de plataformas, linguagens de programação, protocolos e estruturas com suporte.", "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", + "service": "ACR", "severity": "Alto", "subcategory": "Gerenciamento de vulnerabilidades", - "text": "Use plataformas, linguagens, protocolos e frameworks atualizados" + "text": "Use plataformas, linguagens, protocolos e frameworks atualizados", + "waf": "Segurança" } ], "metadata": { - "name": "Azure Container Registry Security Review" + "name": "Azure Container Registry Security Review", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "security" }, "severities": [ { @@ -193,12 +287,37 @@ "name": "Cumprido" }, { - "description": "Não aplicável ao projeto atual", + "description": "Não aplicável para o projeto atual", "name": "N/A" }, { "description": "Não é necessário", "name": "Não é necessário" } + ], + "waf": [ + { + "name": "Fiabilidade" + }, + { + "name": "Segurança" + }, + { + "name": "Custar" + }, + { + "name": "Operações" + }, + { + "name": "Desempenho" + } + ], + "yesno": [ + { + "name": "Sim" + }, + { + "name": "Não" + } ] } \ No newline at end of file diff --git a/checklists/acr_checklist.zh-Hant.json b/checklists/acr_checklist.zh-Hant.json new file mode 100644 index 00000000..c98a3ea2 --- /dev/null +++ b/checklists/acr_checklist.zh-Hant.json @@ -0,0 +1,323 @@ +{ + "categories": [ + { + "name": "安全" + }, + { + "name": "網路拓撲和連接" + }, + { + "name": "運營管理" + }, + { + "name": "平臺自動化" + }, + { + "name": "安全" + }, + { + "name": "分類帳" + }, + { + "name": "伐木" + }, + { + "name": "聯網" + }, + { + "name": "數據發現和分類" + }, + { + "name": "數據掩碼" + }, + { + "name": "法典" + } + ], + "items": [ + { + "category": "安全", + "description": "禁用圖像匯出以防止數據洩露。請注意,這將阻止將映射導入到另一個 ACR 實例中。", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "高", + "subcategory": "數據保護", + "text": "禁用 Azure Container Registry 映射導出", + "waf": "安全" + }, + { + "category": "安全", + "description": "通過為 Azure Container Registry 啟用 Azure Policy 來啟用審核合規性可見性", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "id": "A01.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "高", + "subcategory": "數據保護", + "text": "為 Azure 容器註冊表啟用 Azure 策略", + "waf": "安全" + }, + { + "category": "安全", + "description": "Azure Key Vault (AKV) 用於存儲簽名密鑰,該金鑰可通過表示法 AKV 外掛程式 (azure-kv) 來對容器映像和其他專案進行簽名和驗證。Azure 容器註冊表 (ACR) 允許您使用 az?or?oras? 附加這些簽名。CLI 命令。", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "高", + "subcategory": "數據保護", + "text": "使用符號對容器進行簽名和驗證 (Notary v2)", + "waf": "安全" + }, + { + "category": "安全", + "description": "Azure 容器註冊表會自動加密存儲的映像和其他專案。默認情況下,Azure 使用服務託管密鑰自動加密靜態註冊表內容。通過使用客戶管理的金鑰,您可以使用額外的加密層來補充預設加密。", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "id": "A01.04", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "中等", + "subcategory": "數據保護", + "text": "使用客戶管理的金鑰加密註冊表", + "waf": "安全" + }, + { + "category": "安全", + "description": "使用託管標識保護來自用戶端應用程式的 ACRPull/Push RBAC 訪問", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "id": "A02.01", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "高", + "subcategory": "身份和訪問控制", + "text": "使用託管標識而不是服務主體進行連接", + "waf": "安全" + }, + { + "category": "安全", + "description": "默認情況下,本地管理員帳戶處於禁用狀態,不應啟用。請改用基於 Token 或 RBAC 的訪問方法", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "高", + "subcategory": "身份和訪問控制", + "text": "禁用管理平面訪問的本地身份驗證", + "waf": "安全" + }, + { + "category": "安全", + "description": "禁用管理員帳戶並將 RBAC 角色分配給 ACR 拉取/推送操作的主體", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "id": "A02.03", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "高", + "subcategory": "身份和訪問控制", + "text": "分配AcrPull和AcrPush RBAC角色,而不是授予身份主體管理訪問許可權", + "waf": "安全" + }, + { + "category": "安全", + "description": "禁用匿名拉取/推送訪問", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "id": "A02.04", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "中等", + "subcategory": "身份和訪問控制", + "text": "禁用匿名拉取訪問許可權", + "waf": "安全" + }, + { + "category": "安全", + "description": "令牌身份驗證不支援分配給 AAD 主體。任何可以訪問令牌的人都可以使用提供的任何令牌", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "id": "A02.05", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "高", + "subcategory": "身份和訪問控制", + "text": "禁用存儲庫範圍的訪問令牌", + "waf": "安全" + }, + { + "category": "安全", + "description": "將容器映像部署到受信任網路中專用終結點後面的 ACR", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "id": "A02.06", + "service": "ACR", + "severity": "高", + "subcategory": "身份和訪問控制", + "text": "從受信任的環境部署映像", + "waf": "安全" + }, + { + "category": "安全", + "description": "只有具有 ACR 受眾的令牌才能用於身份驗證。為 ACR 啟用條件存取策略時使用", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "id": "A02.07", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "中等", + "subcategory": "身份和訪問控制", + "text": "禁用 Azure ARM 受眾令牌進行身份驗證", + "waf": "安全" + }, + { + "category": "安全", + "description": "設置一個診斷設置,將『repositoryEvents』和『LoginEvents』發送到Log Analytics作為記錄和監控的中心目標。這允許您監控 ACR 資源本身的控制平面活動。", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "id": "A03.01", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "中等", + "subcategory": "日誌記錄和監控", + "text": "啟用診斷日誌記錄", + "waf": "安全" + }, + { + "category": "安全", + "description": "服務支援通過使用服務級別 IP ACL 篩選規則(而不是 NSG 或 Azure 防火牆)或使用“禁用公用網络訪問”切換開關來禁用公用網络訪問", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "id": "A04.01", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "中等", + "subcategory": "網路安全", + "text": "使用專用連結控制入站網路訪問", + "waf": "安全" + }, + { + "category": "安全", + "description": "如果使用專用連結保護入站網路訪問,則禁用公用網路訪問", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "A04.02", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "中等", + "subcategory": "網路安全", + "text": "禁用公共網路訪問", + "waf": "安全" + }, + { + "category": "安全", + "description": "只有 ACR Premium SKU 支援專用連結訪問", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "id": "A04.03", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "中等", + "subcategory": "網路安全", + "text": "使用支援專用連結的 Azure 容器註冊表 SKU(高級 SKU)", + "waf": "安全" + }, + { + "category": "安全", + "description": "應使用適用於容器的 Azure Defender 或等效服務來掃描容器映像中的漏洞", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "id": "A04.04", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "低", + "subcategory": "網路安全", + "text": "啟用 Defender for Containers 以掃描 Azure 容器註冊表中的漏洞", + "waf": "安全" + }, + { + "category": "安全", + "description": "部署根據 DevSecOps 實踐進行驗證和漏洞掃描的可信代碼。", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "id": "A05.01", + "service": "ACR", + "severity": "中等", + "subcategory": "漏洞管理", + "text": "部署經過驗證的容器映像", + "waf": "安全" + }, + { + "category": "安全", + "description": "使用最新版本的受支援平臺、程式設計語言、協定和框架。", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "id": "A05.02", + "service": "ACR", + "severity": "高", + "subcategory": "漏洞管理", + "text": "使用最新的平臺、語言、協定和框架", + "waf": "安全" + } + ], + "metadata": { + "name": "Azure Container Registry Security Review", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "security" + }, + "severities": [ + { + "name": "高" + }, + { + "name": "中等" + }, + { + "name": "低" + } + ], + "status": [ + { + "description": "尚未查看此檢查", + "name": "未驗證" + }, + { + "description": "存在與此檢查關聯的操作項", + "name": "打開" + }, + { + "description": "此檢查已經過驗證,沒有與之關聯的其他操作項", + "name": "實現" + }, + { + "description": "不適用於當前設計", + "name": "不適用" + }, + { + "description": "不需要", + "name": "不需要" + } + ], + "waf": [ + { + "name": "可靠性" + }, + { + "name": "安全" + }, + { + "name": "成本" + }, + { + "name": "操作" + }, + { + "name": "性能" + } + ], + "yesno": [ + { + "name": "是的" + }, + { + "name": "不" + } + ] +} \ No newline at end of file diff --git a/checklists/checklist.en.master.json b/checklists/checklist.en.master.json index f2fbf17f..9f9a361d 100644 --- a/checklists/checklist.en.master.json +++ b/checklists/checklist.en.master.json @@ -238,8 +238,8 @@ "guid": "c851fd44-7cf1-459c-95a4-f6455d75a981", "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/approaches/cost-management-allocation", "services": [ - "Cost", - "Monitor" + "Monitor", + "Cost" ], "severity": "Medium", "subcategory": "Cost Optimization", @@ -371,6 +371,304 @@ "text": "Consider each Azure resource's scale limits. Organize your resources appropriately, in order to avoid resource organization antipatterns. For example, don't over-architect your solution to work within unrealistic scale requirements.", "waf": "Performance" }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "services": [ + "ACR" + ], + "severity": "High", + "subcategory": "Data Protection", + "text": "Disable Azure Container Registry image export", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "services": [ + "AzurePolicy", + "ACR" + ], + "severity": "High", + "subcategory": "Data Protection", + "text": "Enable Azure Policies for Azure Container Registry", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "services": [ + "AKV", + "ACR" + ], + "severity": "High", + "subcategory": "Data Protection", + "text": "Sign and Verify containers with notation (Notary v2)", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "services": [ + "AKV", + "ACR" + ], + "severity": "Medium", + "subcategory": "Data Protection", + "text": "Encrypt registry with a customer managed key", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "services": [ + "RBAC", + "Entra", + "ACR" + ], + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Use Managed Identities to connect instead of Service Principals", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "services": [ + "RBAC", + "Entra", + "ACR" + ], + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Disable local authentication for management plane access", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "services": [ + "RBAC", + "Entra", + "ACR" + ], + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable anonymous pull/push access", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "services": [ + "Entra", + "ACR" + ], + "severity": "Medium", + "subcategory": "Identity and Access Control", + "text": "Disable Anonymous pull access", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "services": [ + "Entra", + "ACR" + ], + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Disable repository-scoped access tokens", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "services": [ + "PrivateLink", + "EventHubs", + "Entra", + "ACR" + ], + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Deploy images from a trusted environment", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "services": [ + "Entra", + "AzurePolicy", + "ACR" + ], + "severity": "Medium", + "subcategory": "Identity and Access Control", + "text": "Disable Azure ARM audience tokens for authentication", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "services": [ + "Monitor", + "Entra", + "ACR" + ], + "severity": "Medium", + "subcategory": "Logging and Monitoring", + "text": "Enable diagnostics logging", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "services": [ + "PrivateLink", + "VNet", + "Firewall", + "ACR" + ], + "severity": "Medium", + "subcategory": "Network Security", + "text": "Control inbound network access with Private Link", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Disable public network access if inbound network access is secured using Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "services": [ + "PrivateLink", + "ACR" + ], + "severity": "Medium", + "subcategory": "Network Security", + "text": "Disable Public Network access", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Only the ACR Premium SKU supports Private Link access", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "services": [ + "PrivateLink", + "ACR" + ], + "severity": "Medium", + "subcategory": "Network Security", + "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "services": [ + "Defender", + "ACR" + ], + "severity": "Low", + "subcategory": "Network Security", + "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "services": [ + "ACR" + ], + "severity": "Medium", + "subcategory": "Vulnerability Management", + "text": "Deploy validated container images", + "waf": "Security" + }, + { + "category": "Security", + "checklist": "Azure Container Registry Security Review", + "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "services": [ + "ACR" + ], + "severity": "High", + "subcategory": "Vulnerability Management", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "waf": "Security" + }, { "category": "BC and DR", "checklist": "Container Apps Review", @@ -416,8 +714,8 @@ "link": "https://learn.microsoft.com/azure/reliability/reliability-azure-container-apps?tabs=azure-cli#cross-region-disaster-recovery-and-business-continuity", "service": "Container Apps", "services": [ - "FrontDoor", - "TrafficManager" + "TrafficManager", + "FrontDoor" ], "severity": "High", "subcategory": "High Availability", @@ -853,9 +1151,9 @@ "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "service": "VM", "services": [ - "ACR", "Storage", - "VM" + "VM", + "ACR" ], "severity": "Medium", "subcategory": "Virtual Machines", @@ -901,8 +1199,8 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "service": "VM", "services": [ - "VM", "ASR", + "VM", "AVS" ], "severity": "High", @@ -933,8 +1231,8 @@ "link": "https://learn.microsoft.com/azure/quotas/per-vm-quota-requests", "service": "VM", "services": [ - "VM", - "ASR" + "ASR", + "VM" ], "severity": "Medium", "subcategory": "Virtual Machines", @@ -1095,8 +1393,8 @@ "guid": "fe237de2-43b1-46c3-8d7a-a9b7570449aa", "link": "https://learn.microsoft.com/azure/well-architected/devops/automation-infrastructure", "services": [ - "ASR", - "RBAC" + "RBAC", + "ASR" ], "severity": "Medium", "subcategory": "DevOps", @@ -1167,10 +1465,10 @@ "guid": "8df03a82-2cd4-463c-abbc-8ac299ebc92a", "link": "https://learn.microsoft.com/azure/networking/disaster-recovery-dns-traffic-manager", "services": [ - "ASR", - "TrafficManager", "Monitor", - "DNS" + "DNS", + "TrafficManager", + "ASR" ], "severity": "Low", "subcategory": "DNS", @@ -1185,9 +1483,9 @@ "link": "https://learn.microsoft.com/azure/dns/tutorial-dns-private-resolver-failover", "service": "DNS", "services": [ - "ACR", "ASR", - "DNS" + "DNS", + "ACR" ], "severity": "Low", "subcategory": "DNS", @@ -1230,8 +1528,8 @@ "guid": "a359c373-e7dd-4616-83a3-64a907ebae48", "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", "services": [ - "Backup", - "ExpressRoute" + "ExpressRoute", + "Backup" ], "severity": "Medium", "subcategory": "ExpressRoute", @@ -1245,9 +1543,9 @@ "guid": "ead53cc7-de2e-48aa-ab35-71549ab9153d", "link": "https://learn.microsoft.com/azure/expressroute/use-s2s-vpn-as-backup-for-expressroute-privatepeering", "services": [ - "Cost", - "Backup", "ExpressRoute", + "Backup", + "Cost", "VPN" ], "severity": "Low", @@ -1276,8 +1574,8 @@ "guid": "b2b38c88-6ba2-4c02-8499-114a5d3ce574", "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-standard-availability-zones", "services": [ - "VM", - "LoadBalancer" + "LoadBalancer", + "VM" ], "severity": "Low", "subcategory": "Load Balancers", @@ -1291,8 +1589,8 @@ "guid": "dccbd979-2a6b-4cca-8b5f-ea1ebf3dd95d", "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-custom-probe-overview#design-guidance", "services": [ - "LoadBalancer", - "Monitor" + "Monitor", + "LoadBalancer" ], "severity": "Low", "subcategory": "Load Balancers", @@ -1377,8 +1675,8 @@ "guid": "deace4bb-1deb-44c6-9fc3-fc14eeaa3692", "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-resource-providers", "services": [ - "Arc", - "Subscriptions" + "Subscriptions", + "Arc" ], "severity": "High", "subcategory": "General", @@ -1447,8 +1745,8 @@ "guid": "f9ccbd86-8266-4abc-a264-f9a19bf39d95", "link": "https://learn.microsoft.com/azure/azure-arc/servers/organize-inventory-servers#organize-resources-with-built-in-azure-hierarchies", "services": [ - "Arc", - "Subscriptions" + "Subscriptions", + "Arc" ], "severity": "Low", "subcategory": "Organization", @@ -1462,8 +1760,8 @@ "guid": "9bf39d95-d44c-47c8-a19c-a1f6d5215ae5", "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#identity-and-access-control", "services": [ - "Arc", "RBAC", + "Arc", "Entra" ], "severity": "Medium", @@ -1477,8 +1775,8 @@ "guid": "14ba34d4-585e-4111-89bd-7ba012f7b94e", "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/tutorial-windows-vm-access-nonaad", "services": [ - "Arc", "AKV", + "Arc", "Entra" ], "severity": "Low", @@ -1493,9 +1791,9 @@ "guid": "35ac9322-23e1-4380-8523-081a94174158", "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#azure-subscription-and-service-limits", "services": [ + "Subscriptions", "Arc", - "Entra", - "Subscriptions" + "Entra" ], "severity": "High", "subcategory": "Requirements", @@ -1509,8 +1807,8 @@ "guid": "33ee7ad6-c6d3-4733-865c-7acbe44bbe60", "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#required-permissions", "services": [ - "Arc", "RBAC", + "Arc", "Entra" ], "severity": "Medium", @@ -1525,8 +1823,8 @@ "guid": "9d79f2e8-7778-4424-a516-775c6fa95b96", "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale", "services": [ - "Arc", "RBAC", + "Arc", "Entra" ], "severity": "Medium", @@ -1541,8 +1839,8 @@ "guid": "ad88408e-3727-434b-a76b-a28f21459013", "link": "https://learn.microsoft.com/azure/azure-arc/servers/onboard-service-principal#create-a-service-principal-for-onboarding-at-scale", "services": [ - "Arc", "RBAC", + "Arc", "Entra" ], "severity": "Medium", @@ -1557,8 +1855,8 @@ "guid": "65d38e53-f9cc-4bd8-9826-6abca264f9a1", "link": "https://learn.microsoft.com/azure/azure-arc/servers/prerequisites#required-permissions", "services": [ - "Arc", "RBAC", + "Arc", "Entra" ], "severity": "Medium", @@ -1573,8 +1871,8 @@ "guid": "6ee79d6b-5c2a-4364-a4b6-9bad38aad53c", "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Management", @@ -1588,8 +1886,8 @@ "guid": "c78e1d76-6673-457c-9496-74c5ed85b859", "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-agent#upgrade-the-agent", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "High", "subcategory": "Management", @@ -1603,8 +1901,8 @@ "guid": "c7733be2-a1a2-47b7-95a9-1be1f388ff39", "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-vm-extensions", "services": [ - "Arc", "Monitor", + "Arc", "AzurePolicy" ], "severity": "Medium", @@ -1620,8 +1918,8 @@ "guid": "4c2bd463-cbbb-4c86-a195-abb91a4ed90d", "link": "https://learn.microsoft.com/azure/azure-arc/servers/manage-automatic-vm-extension-upgrade?tabs=azure-portal", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "High", "subcategory": "Management", @@ -1635,8 +1933,8 @@ "guid": "7a927c39-74d1-4102-aac6-aae01e6a84de", "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Management", @@ -1649,8 +1947,8 @@ "guid": "37b6b780-cbaf-4e6c-9658-9d457a927c39", "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment#phase-3-manage-and-operate", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "High", "subcategory": "Monitoring", @@ -1663,8 +1961,8 @@ "guid": "74d1102c-ac6a-4ae0-8e6a-84de5df47d2d", "link": "https://learn.microsoft.com/azure/azure-monitor/agents/log-analytics-agent#data-collected", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Monitoring", @@ -1677,8 +1975,8 @@ "guid": "92881b1c-d5d1-4e54-a296-59e3958fd782", "link": "https://learn.microsoft.com/azure/service-health/resource-health-alert-monitor-guide", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Monitoring", @@ -1691,8 +1989,8 @@ "guid": "89c93555-6d02-4bfe-9564-b0d834a34872", "link": "https://learn.microsoft.com/azure/azure-arc/servers/learn/tutorial-enable-vm-insights", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Monitoring", @@ -1705,8 +2003,8 @@ "guid": "5df47d2d-9288-41b1-ad5d-1e54a29659e3", "link": "https://learn.microsoft.com/azure/azure-arc/servers/plan-at-scale-deployment#phase-3-manage-and-operate", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Monitoring", @@ -1721,9 +2019,9 @@ "guid": "ae2cc84c-37b6-4b78-8cba-fe6c46589d45", "link": "https://learn.microsoft.com/azure/update-manager/scheduled-patching?tabs=schedule-updates-single-machine%2Cschedule-updates-scale-overview%2Cwindows-maintenance", "services": [ - "ACR", + "Monitor", "Arc", - "Monitor" + "ACR" ], "severity": "Low", "subcategory": "Security", @@ -1765,10 +2063,10 @@ "guid": "94174158-33ee-47ad-9c6d-3733165c7acb", "link": "https://learn.microsoft.com/azure/azure-arc/servers/private-link-security", "services": [ - "Arc", - "PrivateLink", "ExpressRoute", - "VPN" + "Arc", + "VPN", + "PrivateLink" ], "severity": "Medium", "subcategory": "Networking", @@ -1824,8 +2122,8 @@ "guid": "a264f9a1-9bf3-49d9-9d44-c7c8919ca1f6", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/hybrid/arc-enabled-servers/eslz-arc-servers-connectivity#define-extensions-connectivity-method", "services": [ - "Arc", "PrivateLink", + "Arc", "Monitor" ], "severity": "Low", @@ -1880,8 +2178,8 @@ "guid": "49674c5e-d85b-4859-a773-3be2a1a27b77", "link": "https://learn.microsoft.com/azure/automation/change-tracking/overview", "services": [ - "Arc", - "Monitor" + "Monitor", + "Arc" ], "severity": "Medium", "subcategory": "Monitoring", @@ -1907,8 +2205,8 @@ "guid": "195abb91-a4ed-490d-ae2c-c84c37b6b780", "link": "https://learn.microsoft.com/azure/key-vault/general/basic-concepts", "services": [ - "Arc", - "AKV" + "AKV", + "Arc" ], "severity": "Medium", "subcategory": "Secrets", @@ -1922,9 +2220,9 @@ "guid": "6d02bfe4-564b-40d8-94a3-48726ee79d6b", "link": "https://learn.microsoft.com/azure/active-directory/develop/howto-create-service-principal-portal#option-2-create-a-new-application-secret", "services": [ + "Storage", "AKV", "Arc", - "Storage", "Entra" ], "severity": "High", @@ -1939,8 +2237,8 @@ "guid": "a1a27b77-5a91-4be1-b388-ff394c2bd463", "link": "https://learn.microsoft.com/azure/azure-arc/servers/security-overview#using-disk-encryption", "services": [ - "Arc", - "AKV" + "AKV", + "Arc" ], "severity": "Medium", "subcategory": "Secrets", @@ -2070,8 +2368,8 @@ "service": "Azure Storage", "services": [ "Storage", - "RBAC", - "Subscriptions" + "Subscriptions", + "RBAC" ], "severity": "Medium", "subcategory": "Governance", @@ -2179,8 +2477,8 @@ "service": "Azure Storage", "services": [ "Storage", - "AzurePolicy", - "Subscriptions" + "Subscriptions", + "AzurePolicy" ], "severity": "High", "subcategory": "Data Availability, Compliance", @@ -2273,8 +2571,8 @@ "service": "Azure Storage", "services": [ "Storage", - "RBAC", - "Entra" + "Entra", + "RBAC" ], "severity": "Medium", "subcategory": "Identity and Access Management", @@ -2308,8 +2606,8 @@ "services": [ "Storage", "AKV", - "Monitor", - "Entra" + "Entra", + "Monitor" ], "severity": "High", "subcategory": "Identity and Access Management", @@ -2426,9 +2724,9 @@ "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", "service": "Azure Storage", "services": [ - "AzurePolicy", "Storage", - "Entra" + "Entra", + "AzurePolicy" ], "severity": "High", "subcategory": "Identity and Access Management", @@ -2491,8 +2789,8 @@ "service": "Azure Storage", "services": [ "Storage", - "RBAC", - "Entra" + "Entra", + "RBAC" ], "severity": "High", "subcategory": "Identity and Access Management", @@ -2668,8 +2966,8 @@ "guid": "1fc3fc14-eea6-4e69-b8d9-a3eec218e687", "link": "https://learn.microsoft.com/sql/dma/dma-sku-recommend-sql-db?view=sql-server-ver16", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "VM Size", @@ -2683,8 +2981,8 @@ "guid": "e04abe1f-8d39-4fda-9776-8424c116775c", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-vm-size?view=azuresql#memory-optimized", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "VM Size", @@ -2699,8 +2997,8 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance#counters-to-measure-application-performance-requirements", "services": [ "Storage", - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "Storage", @@ -2744,9 +3042,9 @@ "guid": "25659d35-58fd-4772-99c9-31112d027fe4", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ - "Cost", "Storage", - "SQL" + "SQL", + "Cost" ], "severity": "High", "subcategory": "Storage", @@ -2761,8 +3059,8 @@ "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ "Storage", - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "Storage", @@ -2777,8 +3075,8 @@ "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ "Storage", - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "Storage", @@ -2792,9 +3090,9 @@ "guid": "05674b5e-985b-4859-a773-e7e261623b77", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ - "AzurePolicy", "Storage", - "SQL" + "SQL", + "AzurePolicy" ], "severity": "High", "subcategory": "Storage", @@ -2809,8 +3107,8 @@ "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql#storage", "services": [ "Storage", - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "Storage", @@ -2839,8 +3137,8 @@ "guid": "8b9fe5c4-2049-4d41-9a92-3c3474d11028", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/business-continuity-high-availability-disaster-recovery-hadr-overview?view=azuresql#azure-only-disaster-recovery-solutions", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "HADR", @@ -2854,8 +3152,8 @@ "guid": "ac6aae01-e6a8-44de-9df4-3d1992481718", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/business-continuity-high-availability-disaster-recovery-hadr-overview?view=azuresql#high-availability-nodes-in-an-availability-set", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "HADR", @@ -2869,10 +3167,10 @@ "guid": "d5d1e5f6-2565-49d3-958f-d77249c93111", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/availability-group-azure-portal-configure?view=azuresql&tabs=azure-cli", "services": [ - "VM", "LoadBalancer", + "VNet", "SQL", - "VNet" + "VM" ], "severity": "Medium", "subcategory": "HADR", @@ -2915,10 +3213,10 @@ "guid": "667313c4-0567-44b5-b985-b859c773e7e2", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/availability-group-vnn-azure-load-balancer-configure?view=azuresql-vm&tabs=ilb", "services": [ - "VM", "LoadBalancer", + "VNet", "SQL", - "VNet" + "VM" ], "severity": "High", "subcategory": "HADR", @@ -2977,8 +3275,8 @@ "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/performance-guidelines-best-practices-checklist?view=azuresql-vm#sql-server-features", "services": [ "Storage", - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Low", "subcategory": "SQL Server", @@ -2992,8 +3290,8 @@ "guid": "d68c5b5c-2925-4394-a69a-9d2799c42bb6", "link": "https://learn.microsoft.com/sql/database-engine/configure-windows/server-memory-server-configuration-options#use-", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "SQL Server", @@ -3007,8 +3305,8 @@ "guid": "8d1d7555-6246-4b43-a563-b4dc74a748b6", "link": "https://learn.microsoft.com/sql/database-engine/configure-windows/enable-the-lock-pages-in-memory-option-windows", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "SQL Server", @@ -3022,8 +3320,8 @@ "guid": "633ad2a0-916a-4664-a8fa-d0e278ee293c", "link": "https://learn.microsoft.com/sql/relational-databases/performance/monitoring-performance-by-using-the-query-store", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Low", "subcategory": "SQL Server", @@ -3037,8 +3335,8 @@ "guid": "1bc352ba-aab7-4571-a49a-b8093dc9ec9d", "link": "https://learn.microsoft.com/sql/relational-databases/databases/tempdb-database#optimizing-tempdb-performance-in-sql-server", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "SQL Server", @@ -3052,8 +3350,8 @@ "guid": "1bb73b36-a5a6-47fb-a9ed-5b35478c3479", "link": "https://docs.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "SQL Server", @@ -3067,8 +3365,8 @@ "guid": "816b2863-cffe-41ca-a599-ef0d5a73dd4c", "link": "https://docs.microsoft.com/azure/governance/management-groups/how-to/protect-resource-hierarchy#setting---require-authorization", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "SQL Server", @@ -3082,10 +3380,10 @@ "guid": "e36c1c81-770a-4fbc-9c0d-43918648d285", "link": "https://learn.microsoft.com/azure/virtual-machines/constrained-vcpu", "services": [ - "Cost", "Storage", + "SQL", "VM", - "SQL" + "Cost" ], "severity": "Low", "subcategory": "Cost Optimization", @@ -3100,8 +3398,8 @@ "guid": "7ed67178-b824-4546-ae1a-ee3453aec823", "link": "https://azure.microsoft.com/en-ca/pricing/hybrid-benefit/", "services": [ - "Cost", - "SQL" + "SQL", + "Cost" ], "severity": "Low", "subcategory": "Cost Optimization", @@ -3115,8 +3413,8 @@ "guid": "9248725d-d68c-45b5-a292-5394a69a9d27", "link": "https://learn.microsoft.com/azure/azure-sql/virtual-machines/windows/sql-agent-extension-automatic-registration-all-vms?view=azuresql-vm&tabs=azure-cli", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "Azure", @@ -3131,8 +3429,8 @@ "guid": "99c42bb6-8d1d-4755-9624-6b438563b4dc", "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview?tabs=redhat", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "Azure", @@ -3147,8 +3445,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/secure-score-security-controls", "services": [ "Defender", - "VM", - "SQL" + "SQL", + "VM" ], "severity": "High", "subcategory": "Azure", @@ -3254,8 +3552,8 @@ "guid": "eaded26b-dd18-46f0-ac25-1b999a68af87", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/frequently-asked-questions-faq?view=azuresql-mi#can-a-managed-instance-have-the-same-name-as-a-sql-server-on-premises-instance", "services": [ - "DNS", - "SQL" + "SQL", + "DNS" ], "severity": "High", "subcategory": "Pre Migration", @@ -3270,8 +3568,8 @@ "guid": "c9a7f821-b8eb-48c0-aa77-e25e4d5aeaa8", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/vnet-existing-add-subnet?view=azuresql-mi", "services": [ - "SQL", - "VNet" + "VNet", + "SQL" ], "severity": "Medium", "subcategory": "Pre Migration", @@ -3286,8 +3584,8 @@ "guid": "dc4e2436-bb33-46d7-85f1-7960eee0b9b5", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/vnet-subnet-determine-size?view=azuresql-mi", "services": [ - "SQL", - "VNet" + "VNet", + "SQL" ], "severity": "High", "subcategory": "Deployment", @@ -3406,8 +3704,8 @@ "guid": "829e3eec-2183-4687-a007-7a2b5945bda4", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/tde-certificate-migrate?view=azuresql-mi&tabs=azure-powershell", "services": [ - "VM", - "SQL" + "SQL", + "VM" ], "severity": "Medium", "subcategory": "Deployment", @@ -3421,8 +3719,8 @@ "guid": "3334fdf9-1c23-4418-8b65-275269440b4b", "link": "https://learn.microsoft.com/azure/azure-sql/migration-guides/managed-instance/sql-server-to-managed-instance-guide?view=azuresql-mi#backup-and-restore", "services": [ - "Backup", - "SQL" + "SQL", + "Backup" ], "severity": "Low", "subcategory": "Migration", @@ -3478,8 +3776,8 @@ "guid": "141acdce-5793-477b-adb3-751ab2ac1fad", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/auto-failover-group-configure-sql-mi?view=azuresql&tabs=azure-portal#test-failover", "services": [ - "EventHubs", "LoadBalancer", + "EventHubs", "SQL" ], "severity": "High", @@ -3511,9 +3809,9 @@ "link": "https://learn.microsoft.com/azure/architecture/example-scenario/data/sql-managed-instance-cmk", "services": [ "AKV", - "AzurePolicy", + "SQL", "Backup", - "SQL" + "AzurePolicy" ], "severity": "Low", "subcategory": "Post Migration", @@ -3544,9 +3842,9 @@ "link": "https://learn.microsoft.com/azure/azure-sql/database/long-term-retention-overview?view=azuresql-mi", "services": [ "Storage", - "Backup", "ARS", - "SQL" + "SQL", + "Backup" ], "severity": "Low", "subcategory": "Post Migration", @@ -3561,8 +3859,8 @@ "guid": "ad88408f-3727-434c-a76b-a28021459014", "link": "https://azure.microsoft.com/en-gb/pricing/hybrid-benefit/#overview", "services": [ - "Cost", - "SQL" + "SQL", + "Cost" ], "severity": "Low", "subcategory": "Post Migration", @@ -3577,8 +3875,8 @@ "guid": "65d38e53-f9cc-4bd8-9926-6acca274faa1", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-overview?view=azuresql", "services": [ - "Defender", - "SQL" + "SQL", + "Defender" ], "severity": "Medium", "subcategory": "Post Migration", @@ -3624,8 +3922,8 @@ "service": "SAP", "services": [ "ASR", - "SAP", - "Backup" + "Backup", + "SAP" ], "severity": "Medium", "subcategory": "Backup and restore", @@ -3654,10 +3952,10 @@ "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", "service": "SAP", "services": [ - "ASR", "Backup", - "Storage", "SAP", + "Storage", + "ASR", "SQL" ], "severity": "High", @@ -3708,10 +4006,10 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", "service": "SAP", "services": [ - "ACR", "ASR", "AKV", - "SAP" + "SAP", + "ACR" ], "severity": "Low", "subcategory": "Disaster recovery", @@ -3726,8 +4024,8 @@ "service": "SAP", "services": [ "ASR", - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "Medium", "subcategory": "Disaster recovery", @@ -3776,8 +4074,8 @@ "service": "SAP", "services": [ "ASR", - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "High", "subcategory": "Disaster recovery", @@ -3791,10 +4089,10 @@ "guid": "0258ed30-fe42-434f-87b9-58f91f908e0a", "service": "SAP", "services": [ - "VM", "ASR", - "SAP", - "Entra" + "VM", + "Entra", + "SAP" ], "severity": "High", "subcategory": "Disaster recovery", @@ -3842,9 +4140,9 @@ "service": "SAP", "services": [ "Storage", + "ASR", "VM", - "SAP", - "ASR" + "SAP" ], "severity": "High", "subcategory": "High availability", @@ -3945,8 +4243,8 @@ "services": [ "ASR", "VM", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "High", "subcategory": "High availability", @@ -3960,11 +4258,11 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/availability-set-overview", "service": "SAP", "services": [ - "ASR", "RBAC", - "SAP", "VM", - "Entra" + "SAP", + "Entra", + "ASR" ], "severity": "High", "subcategory": "High availability", @@ -4013,8 +4311,8 @@ "service": "SAP", "services": [ "ASR", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "High", "subcategory": "High availability", @@ -4028,9 +4326,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/proximity-placement-scenarios", "service": "SAP", "services": [ - "ACR", "ASR", - "SAP" + "SAP", + "ACR" ], "severity": "High", "subcategory": "High availability", @@ -4045,8 +4343,8 @@ "service": "SAP", "services": [ "ASR", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "High", "subcategory": "High availability", @@ -4063,8 +4361,8 @@ "services": [ "ASR", "VM", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "High availability", @@ -4081,9 +4379,9 @@ "service": "SAP", "services": [ "Storage", + "ASR", "VM", - "SAP", - "ASR" + "SAP" ], "severity": "Medium", "subcategory": "High availability", @@ -4180,8 +4478,8 @@ "link": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/optimize-your-azure-costs-by-automating-sap-system-start-stop/ba-p/2120675", "service": "SAP", "services": [ - "Cost", - "SAP" + "SAP", + "Cost" ], "severity": "Medium", "subcategory": " ", @@ -4195,10 +4493,10 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/hana-vm-premium-ssd-v1", "service": "SAP", "services": [ - "Cost", "Storage", "VM", - "SAP" + "SAP", + "Cost" ], "severity": "Low", "subcategory": " ", @@ -4212,10 +4510,10 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/hana-vm-premium-ssd-v1", "service": "SAP", "services": [ - "Cost", "Storage", "VM", - "SAP" + "SAP", + "Cost" ], "severity": "Low", "subcategory": " ", @@ -4231,9 +4529,9 @@ "service": "SAP", "services": [ "RBAC", - "SAP", + "Subscriptions", "Entra", - "Subscriptions" + "SAP" ], "severity": "High", "subcategory": "Identity", @@ -4248,8 +4546,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/scenario-azure-first-sap-identity-integration", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4264,8 +4562,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/scenario-azure-first-sap-identity-integration", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4279,8 +4577,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4294,8 +4592,8 @@ "guid": "9eb54dad-7861-4e1c-973a-f3bb003fc9c1", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4310,8 +4608,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4326,8 +4624,8 @@ "service": "SAP", "services": [ "AKV", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4343,8 +4641,8 @@ "service": "SAP", "services": [ "AKV", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4358,8 +4656,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-netweaver-tutorial#configure-sap-netweaver-for-oauth", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4373,8 +4671,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/saphana-tutorial", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4388,8 +4686,8 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/rise-integration#connectivity-with-sap-rise", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4403,8 +4701,8 @@ "link": "https://github.com/azuredevcollege/SAP/blob/master/sap-oauth-saml-flow/README.md", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4418,8 +4716,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-hana-cloud-platform-identity-authentication-tutorial", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4433,8 +4731,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-hana-cloud-platform-tutorial", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4448,8 +4746,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/saas-apps/sap-successfactors-inbound-provisioning-cloud-only-tutorial", "service": "SAP", "services": [ - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Identity", @@ -4465,9 +4763,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", "service": "SAP", "services": [ - "SAP", "AzurePolicy", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -4483,8 +4781,8 @@ "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", "service": "SAP", "services": [ - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Subscriptions", @@ -4500,8 +4798,8 @@ "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", "service": "SAP", "services": [ - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Subscriptions", @@ -4518,8 +4816,8 @@ "service": "SAP", "services": [ "VM", - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Subscriptions", @@ -4534,8 +4832,8 @@ "link": "https://learn.microsoft.com/rest/api/reserved-vm-instances/quotaapi?branch=capacity", "service": "SAP", "services": [ - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "Low", "subcategory": "Subscriptions", @@ -4550,8 +4848,8 @@ "service": "SAP", "services": [ "VM", - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Subscriptions", @@ -4565,8 +4863,8 @@ "link": "https://azure.microsoft.com/explore/global-infrastructure/products-by-region/", "service": "SAP", "services": [ - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Subscriptions", @@ -4582,10 +4880,10 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-resource-organization", "service": "SAP", "services": [ - "Cost", + "Subscriptions", "TrafficManager", "SAP", - "Subscriptions" + "Cost" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -4600,9 +4898,9 @@ "link": "https://learn.microsoft.com/azure/backup/sap-hana-database-about", "service": "SAP", "services": [ + "Monitor", "Backup", - "SAP", - "Monitor" + "SAP" ], "severity": "High", "subcategory": "BCDR", @@ -4617,11 +4915,11 @@ "link": "https://learn.microsoft.com/azure/azure-netapp-files/azacsnap-introduction", "service": "SAP", "services": [ - "Monitor", - "Storage", - "SAP", "VM", - "Entra" + "SAP", + "Storage", + "Entra", + "Monitor" ], "severity": "Medium", "subcategory": "BCDR", @@ -4635,8 +4933,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-management-and-monitoring", "service": "SAP", "services": [ - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "High", "subcategory": "Management", @@ -4651,8 +4949,8 @@ "service": "SAP", "services": [ "Monitor", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Management", @@ -4667,9 +4965,9 @@ "link": "https://azure.microsoft.com/pricing/offers/dev-test/", "service": "SAP", "services": [ - "Cost", + "Monitor", "SAP", - "Monitor" + "Cost" ], "severity": "Low", "subcategory": "Management", @@ -4684,8 +4982,8 @@ "service": "SAP", "services": [ "Monitor", - "SAP", - "Entra" + "Entra", + "SAP" ], "severity": "Medium", "subcategory": "Management", @@ -4699,9 +4997,9 @@ "link": "https://learn.microsoft.com/azure/update-manager/scheduled-patching?tabs=schedule-updates-single-machine%2Cschedule-updates-scale-overview", "service": "SAP", "services": [ + "Monitor", "VM", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": "Management", @@ -4716,8 +5014,8 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/lama-installation", "service": "SAP", "services": [ - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "Low", "subcategory": "Management", @@ -4732,9 +5030,9 @@ "link": "https://learn.microsoft.com/azure/sap/monitor/about-azure-monitor-sap-solutions", "service": "SAP", "services": [ + "Monitor", "SQL", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4749,10 +5047,10 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/vm-extension-for-sap", "service": "SAP", "services": [ - "VM", - "SAP", "Monitor", - "Entra" + "VM", + "Entra", + "SAP" ], "severity": "High", "subcategory": "Monitoring", @@ -4768,8 +5066,8 @@ "service": "SAP", "services": [ "Monitor", - "SAP", - "AzurePolicy" + "AzurePolicy", + "SAP" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4784,9 +5082,9 @@ "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-overview", "service": "SAP", "services": [ - "SAP", "Monitor", - "NetworkWatcher" + "NetworkWatcher", + "SAP" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4801,9 +5099,9 @@ "link": "https://github.com/Azure/SAP-on-Azure-Scripts-and-Utilities/tree/main/QualityCheck", "service": "SAP", "services": [ + "Monitor", "VM", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4817,9 +5115,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/high-availability-zones", "service": "SAP", "services": [ - "SAP", "Monitor", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Monitoring", @@ -4836,8 +5134,8 @@ "services": [ "Storage", "ASR", - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4852,9 +5150,9 @@ "link": "https://learn.microsoft.com/azure/sentinel/sap/deployment-overview", "service": "SAP", "services": [ + "Monitor", "Sentinel", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4870,9 +5168,9 @@ "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance", "service": "SAP", "services": [ - "Cost", + "Monitor", "SAP", - "Monitor" + "Cost" ], "severity": "Medium", "subcategory": "Monitoring", @@ -4887,9 +5185,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-test-latency?tabs=windows", "service": "SAP", "services": [ + "Monitor", "VM", - "SAP", - "Monitor" + "SAP" ], "severity": "Low", "subcategory": "Performance", @@ -4903,9 +5201,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide-storage", "service": "SAP", "services": [ + "Monitor", "ASR", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": "Performance", @@ -4921,8 +5219,8 @@ "service": "SAP", "services": [ "Storage", - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "Medium", "subcategory": "Performance", @@ -4936,8 +5234,8 @@ "link": "https://sapit-forme-prod.authentication.eu11.hana.ondemand.com/login", "service": "SAP", "services": [ - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "Low", "subcategory": "Performance", @@ -4952,8 +5250,8 @@ "service": "SAP", "services": [ "Storage", - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "Medium", "subcategory": "Performance", @@ -4969,8 +5267,8 @@ "service": "SAP", "services": [ "Monitor", - "SAP", - "SQL" + "SQL", + "SAP" ], "severity": "Medium", "subcategory": "Performance", @@ -4985,9 +5283,9 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-monitor-and-troubleshoot", "service": "SAP", "services": [ + "Monitor", "ASR", - "SAP", - "Monitor" + "SAP" ], "severity": "High", "subcategory": "Reliability", @@ -5002,10 +5300,10 @@ "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "service": "SAP", "services": [ - "AppGW", - "SAP", + "WAF", "AzurePolicy", - "WAF" + "AppGW", + "SAP" ], "severity": "Medium", "subcategory": "App delivery", @@ -5021,8 +5319,8 @@ "service": "SAP", "services": [ "VM", - "SAP", - "DNS" + "DNS", + "SAP" ], "severity": "Medium", "subcategory": "DNS", @@ -5037,9 +5335,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", "service": "SAP", "services": [ + "VNet", "DNS", - "SAP", - "VNet" + "SAP" ], "severity": "Medium", "subcategory": "DNS", @@ -5056,9 +5354,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-peering-overview", "service": "SAP", "services": [ - "ACR", + "VNet", "SAP", - "VNet" + "ACR" ], "severity": "Medium", "subcategory": "Hybrid", @@ -5073,8 +5371,8 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide", "service": "SAP", "services": [ - "NVA", - "SAP" + "SAP", + "NVA" ], "severity": "High", "subcategory": "Hybrid", @@ -5090,9 +5388,9 @@ "link": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/?source=recommendations", "service": "SAP", "services": [ - "ACR", + "VWAN", "SAP", - "VWAN" + "ACR" ], "severity": "Medium", "subcategory": "Hybrid", @@ -5107,9 +5405,9 @@ "link": "https://learn.microsoft.com/azure/well-architected/services/networking/network-virtual-appliances/reliability", "service": "SAP", "services": [ - "NVA", + "VNet", "SAP", - "VNet" + "NVA" ], "severity": "Medium", "subcategory": "Hybrid", @@ -5124,10 +5422,10 @@ "link": "https://learn.microsoft.com/azure/architecture/networking/hub-spoke-vwan-architecture", "service": "SAP", "services": [ - "NVA", - "SAP", + "VNet", "VWAN", - "VNet" + "SAP", + "NVA" ], "severity": "Medium", "subcategory": "Hybrid", @@ -5143,9 +5441,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "service": "SAP", "services": [ + "VNet", "VM", - "SAP", - "VNet" + "SAP" ], "severity": "High", "subcategory": "IP plan", @@ -5162,8 +5460,8 @@ "service": "SAP", "services": [ "ASR", - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "High", "subcategory": "IP plan", @@ -5178,8 +5476,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "service": "SAP", "services": [ - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "High", "subcategory": "IP plan", @@ -5195,8 +5493,8 @@ "service": "SAP", "services": [ "Storage", - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "Medium", "subcategory": "IP plan", @@ -5228,9 +5526,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/expose-sap-process-orchestration-on-azure", "service": "SAP", "services": [ + "WAF", "AppGW", - "SAP", - "WAF" + "SAP" ], "severity": "Medium", "subcategory": "Internet", @@ -5245,11 +5543,11 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "SAP", "services": [ - "ACR", - "SAP", "WAF", + "ACR", "FrontDoor", - "AzurePolicy" + "AzurePolicy", + "SAP" ], "severity": "Medium", "subcategory": "Internet", @@ -5265,10 +5563,10 @@ "service": "SAP", "services": [ "AppGW", - "SAP", "WAF", "FrontDoor", - "AzurePolicy" + "AzurePolicy", + "SAP" ], "severity": "Medium", "subcategory": "Internet", @@ -5283,10 +5581,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "SAP", "services": [ - "AppGW", - "SAP", + "WAF", "LoadBalancer", - "WAF" + "AppGW", + "SAP" ], "severity": "Medium", "subcategory": "Internet", @@ -5301,9 +5599,9 @@ "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", "service": "SAP", "services": [ - "ACR", + "VWAN", "SAP", - "VWAN" + "ACR" ], "severity": "Medium", "subcategory": "Internet", @@ -5318,12 +5616,12 @@ "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "service": "SAP", "services": [ + "PrivateLink", "ACR", "Backup", - "Storage", "SAP", - "VNet", - "PrivateLink" + "Storage", + "VNet" ], "severity": "Medium", "subcategory": "Internet", @@ -5372,9 +5670,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "service": "SAP", "services": [ + "VNet", "VM", - "SAP", - "VNet" + "SAP" ], "severity": "Medium", "subcategory": "Segmentation", @@ -5389,8 +5687,8 @@ "link": "https://me.sap.com/notes/2015553", "service": "SAP", "services": [ - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "High", "subcategory": "Segmentation", @@ -5435,9 +5733,9 @@ "link": "https://me.sap.com/notes/2015553", "service": "SAP", "services": [ - "Cost", + "VNet", "SAP", - "VNet" + "Cost" ], "severity": "High", "subcategory": "Segmentation", @@ -5468,8 +5766,8 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/rise-integration", "service": "SAP", "services": [ - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "Medium", "subcategory": "Segmentation", @@ -5484,8 +5782,8 @@ "service": "SAP", "services": [ "VM", - "SAP", - "Backup" + "Backup", + "SAP" ], "severity": "High", "subcategory": " ", @@ -5499,9 +5797,9 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-monitor-and-troubleshoot", "service": "SAP", "services": [ + "Monitor", "ASR", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": " ", @@ -5515,8 +5813,8 @@ "link": "https://help.sap.com/docs/SAP_HANA_PLATFORM/c4d7c773af4a4e5dbebb6548d6e2d4f4/e3111d2ebb5710149510cc120646bf3f.html?locale=en-US", "service": "SAP", "services": [ - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "High", "subcategory": " ", @@ -5531,8 +5829,8 @@ "service": "SAP", "services": [ "VM", - "SAP", - "Backup" + "Backup", + "SAP" ], "severity": "Medium", "subcategory": " ", @@ -5547,8 +5845,8 @@ "service": "SAP", "services": [ "Storage", - "SAP", - "SQL" + "SQL", + "SAP" ], "severity": "Medium", "subcategory": " ", @@ -5563,8 +5861,8 @@ "service": "SAP", "services": [ "VM", - "SAP", - "Backup" + "Backup", + "SAP" ], "severity": "Medium", "subcategory": " ", @@ -5634,9 +5932,9 @@ "guid": "62fbf0f8-51db-49e1-a961-bb5df7a35f80", "service": "SAP", "services": [ + "Monitor", "SQL", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": " ", @@ -5666,8 +5964,8 @@ "link": "https://learn.microsoft.com/en-us/azure/sap/large-instances/hana-monitor-troubleshoot", "service": "SAP", "services": [ - "SAP", - "Monitor" + "Monitor", + "SAP" ], "severity": "Medium", "subcategory": " ", @@ -5726,8 +6024,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/sap-lza-database-security", "service": "SAP", "services": [ - "SAP", - "SQL" + "SQL", + "SAP" ], "severity": "Low", "subcategory": "Governance", @@ -5741,8 +6039,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/sap-lza-database-security", "service": "SAP", "services": [ - "SAP", - "SQL" + "SQL", + "SAP" ], "severity": "High", "subcategory": "Governance", @@ -5757,11 +6055,11 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-security-governance-and-compliance", "service": "SAP", "services": [ - "AKV", "Backup", - "Storage", "SAP", - "SQL" + "Storage", + "SQL", + "AKV" ], "severity": "High", "subcategory": "Secrets", @@ -5810,11 +6108,11 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", "service": "SAP", "services": [ - "AKV", "RBAC", + "AzurePolicy", "SAP", "Subscriptions", - "AzurePolicy" + "AKV" ], "severity": "Medium", "subcategory": "Secrets", @@ -5829,9 +6127,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview", "service": "SAP", "services": [ + "AzurePolicy", "AKV", - "SAP", - "AzurePolicy" + "SAP" ], "severity": "Medium", "subcategory": "Secrets", @@ -5846,10 +6144,10 @@ "link": "https://learn.microsoft.com/azure/role-based-access-control/security-controls-policy", "service": "SAP", "services": [ - "AKV", "RBAC", - "SAP", - "AzurePolicy" + "AzurePolicy", + "AKV", + "SAP" ], "severity": "High", "subcategory": "Secrets", @@ -5866,8 +6164,8 @@ "services": [ "Storage", "AKV", - "SAP", - "Defender" + "Defender", + "SAP" ], "severity": "High", "subcategory": "Secrets", @@ -5882,9 +6180,9 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/just-in-time-access-overview?tabs=defender-for-container-arch-aks", "service": "SAP", "services": [ + "RBAC", "AKV", "Defender", - "RBAC", "SAP" ], "severity": "High", @@ -5966,8 +6264,8 @@ "service": "SAP", "services": [ "RBAC", - "SAP", - "Subscriptions" + "Subscriptions", + "SAP" ], "severity": "High", "subcategory": "Security", @@ -5982,9 +6280,9 @@ "link": "https://blogs.sap.com/2019/07/21/sap-security-operations-on-azure/", "service": "SAP", "services": [ - "NVA", "PrivateLink", - "SAP" + "SAP", + "NVA" ], "severity": "High", "subcategory": "Security", @@ -6032,8 +6330,8 @@ "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-whole-landscape", "service": "SAP", "services": [ - "SAP", - "VNet" + "VNet", + "SAP" ], "severity": "High", "subcategory": "Security", @@ -6048,8 +6346,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-security-governance-and-compliance", "service": "SAP", "services": [ - "SAP", - "WAF" + "WAF", + "SAP" ], "severity": "Low", "subcategory": "Security", @@ -6064,9 +6362,9 @@ "link": "https://learn.microsoft.com/azure/sap/monitor/enable-tls-azure-monitor-sap-solutions", "service": "SAP", "services": [ + "Monitor", "AKV", - "SAP", - "Monitor" + "SAP" ], "severity": "Medium", "subcategory": "Security", @@ -6075,672 +6373,819 @@ "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Leverage zone-redundancy to ensure high availability in the event of zone-level failures. Use Premium V2/V3 or Isolated v2 tiers, which provide support for zone-redundant deployments and ensure minimal downtime during disasters.", - "guid": "b32e1aa1-4813-4602-88fe-27ca2891f421", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/app-service-web-app/zone-redundant?source=recommendations", - "service": "App Services", + "category": "BCDR", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Ensure that your backups are protected against attacks. This should include encryption of the backups to protect against loss of confidentiality. For regular Azure service backup, backup data is automatically encrypted using Azure platform-managed keys. You can also choose to encrypt the backup using a customer-managed key. In this case, ensure this customer-managed key in the key vault is also in the backup scope.", + "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", "services": [ - "AppSvc" + "SQL", + "AKV", + "Backup" ], - "severity": "Low", - "subcategory": "High Availability", - "text": "Implement a baseline highly available zone-redundant web application architecture. Ensure your Azure App Service is on Premium V2/V3 or Isolated v2 tiers for zone-redundant support.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Azure Key Vault", + "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Leverage staging slots for zero-downtime deployments and automated backups to ensure disaster recovery. Choose the appropriate tier (Standard or Premium) based on the number of slots and disaster recovery requirements.", - "graph": "resources | where type =~ 'microsoft.web/serverfarms' | extend compliant = (sku.tier == 'Premium' or sku.tier == 'Standard') | distinct id,compliant", - "guid": "e4b31c6a-2e3f-4df1-8e8b-9c3aa5a27820", - "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", - "service": "App Services", + "category": "BCDR", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database uses SQL Server technology to create full backups every week, differential backup every 12-24 hours, and transaction log backup every 5 to 10 minutes. By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region.", + "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", "services": [ - "ASR", - "AppSvc", + "Storage", + "SQL", "Backup" ], "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Premium and Standard tiers for staging slots and automated backups. Align your backup retention period with disaster recovery needs.", - "waf": "Reliability" + "subcategory": "Backup", + "text": "Configure Azure SQL Database automated backups", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Availability Zones provide physical isolation across datacenters in a region, reducing downtime during outages. Verify your region supports Availability Zones and use Premium V2/V3 tiers for zone-redundant deployments.", - "guid": "a7e2e6c2-491f-4fa4-a82b-521d0bc3b202", - "link": "https://learn.microsoft.com/azure/reliability/migrate-app-service", - "service": "App Services", + "category": "BCDR", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region. For SQL Database, the backup storage redundancy can be configured at the time of database creation or can be updated for an existing database; the changes made to an existing database apply to future backups only.", + "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", "services": [ - "ACR", - "AppSvc" + "Storage", + "SQL", + "Backup" ], - "severity": "High", - "subcategory": "High Availability", - "text": "Leverage Availability Zones where regionally applicable (Premium V2/V3 tier required). Check region support for Availability Zones.", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Backup", + "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", + "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure App Service Review", - "description": "Enable health checks to detect unhealthy instances in real-time and automatically replace them to maintain high availability and application reliability.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.HealthCheckPath != '') | distinct id,compliant", - "guid": "1275e4a9-7b6a-43c3-a9cd-5ee18d8995ad", - "link": "https://learn.microsoft.com/azure/app-service/monitor-instances-health-check", - "service": "App Services", + "category": "Code", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Malicious code can potentially circumvent security controls. Before deploying custom code to production, it is essential to review what's being deployed. Use a database tool like Azure Data Studio that supports source control. Implement tools and logic for code analysis, vulnerability and credential scanning.", + "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "services": [ - "AppSvc", - "Monitor" + "SQL" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Implement health checks to monitor and detect issues with App Service instances. Health checks enable automatic instance replacement on failure.", - "waf": "Reliability" + "subcategory": "Source Control and Code Review", + "text": "Use Source Control systems to store, maintain and review application code deployed inside Azure SQLDB Database", + "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure App Service Review", - "description": "Follow best practices for configuring backups and restores in Azure App Service and ASE to guarantee data availability and ensure recovery during disaster scenarios.", - "guid": "35a91c5d-4ad6-4d9b-8e0f-c47db9e6d1e7", - "link": "https://learn.microsoft.com/azure/app-service/manage-backup", - "service": "App Services", + "category": "Data Discovery and Classification", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "In case of classification requirements Purview is the preferred option. Only use SQL Data Discovery & Classification in case Purview is not an option. Discover columns that potentially contain sensitive data. What is considered sensitive data heavily depends on the customer, compliance regulation, etc., and needs to be evaluated by the users in charge of that data. Classify the columns to use advanced sensitivity-based auditing and protection scenarios. Review results of automated discovery and finalize the classification if necessary.", + "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", "services": [ - "AppSvc", - "Backup" + "SQL" ], - "severity": "High", - "subcategory": "Multi-tenant service", - "text": "Refer to backup and restore best practices for Azure App Service and App Service Environments (ASE) to ensure data availability and recovery.", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Data Discovery and Classification", + "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Ensure high availability by incorporating scaling, fault tolerance, monitoring, and zone redundancy into your App Service architecture. Leverage health checks and availability zones to maintain uptime.", - "guid": "e68cd0ec-afc6-4bd8-a27f-7860ad9a0db2", - "link": "https://learn.microsoft.com/azure/architecture/framework/services/compute/azure-app-service/reliability", - "service": "App Services", + "category": "Data Masking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Usage of this feature is recommended only if column encryption is not an option and there is a specific requirement to preserve data types and formats. Dynamic data masking limits sensitive data exposure by masking it to non-privileged users. Dynamic data masking helps prevent unauthorized access to sensitive data by enabling customers to designate how much of the sensitive data to reveal with minimal impact on the application layer.", + "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", "services": [ - "AppSvc", - "Monitor" + "SQL" + ], + "severity": "Low", + "subcategory": "Data Masking", + "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible", + "waf": "Security" + }, + { + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "SQL Advanced Threat Detection (ATP) provides a layer of security that detects potential vulnerabilities and anomalous activity in databases such as SQL injection attacks and unusual behavior patterns. When a potential threat is detected Threat Detection sends an actionable real-time alert by email and in Microsoft Defender for Cloud, which includes clear investigation and remediation steps for the specific threat.", + "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "services": [ + "EventHubs", + "SQL", + "Defender" ], "severity": "High", - "subcategory": "High Availability", - "text": "Implement Azure App Service reliability best practices, including auto-scaling, fault tolerance, health checks, and zone redundancy.", - "waf": "Reliability" + "subcategory": "Advanced Threat Protection", + "text": "Review and complete Advanced Threat Protection (ATP) configuration", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Prepare for disaster recovery by implementing region failover strategies. Utilize active-active and active-passive configurations, automated failover, and Infrastructure as Code (IaC) for seamless failover during outages.", - "guid": "bd2a865c-0835-4418-bb58-4df91a5a9b3f", - "link": "https://learn.microsoft.com/azure/app-service/manage-disaster-recovery#recover-app-content-only", - "service": "App Services", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Enable Microsoft Defender for Azure SQL at the subscription level to automatically onboard and protect all existing and future servers and databases. When you enable on the subscription level, all databases in Azure SQL Database and Azure SQL Managed Instance are protected. You can then disable them individually if you choose. If you want to manually manage which databases are protected, disable at the subscription level and enable each database that you want protected.", + "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", "services": [ - "ASR", - "AppSvc" + "SQL", + "Subscriptions", + "Defender" ], - "severity": "Low", - "subcategory": "High Availability", - "text": "Familiarize with App Service region failover, including active-active and active-passive configurations, automated failover, and IaC deployment.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Defender for Azure SQL", + "text": "Enable Microsoft Defender for Azure SQL", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Azure App Service offers built-in reliability features, including scaling, fault tolerance, and service-level agreements (SLAs). Leverage these features to maintain consistent performance during outages.", - "guid": "f3d2f1e4-e6d4-4b7a-a5a5-e2a9b2c6f293", - "link": "https://learn.microsoft.com/azure/reliability/reliability-app-service", - "service": "App Services", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Microsoft Defender for Azure SQL ATP detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. Alerts can be configured and generated and will be reported in the Defender for console.", + "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "services": [ - "AppSvc" + "Monitor", + "SQL", + "Defender" ], "severity": "High", - "subcategory": "High Availability", - "text": "Familiarize with reliability support in Azure App Service, including scaling options, SLAs, and automated recovery mechanisms.", - "waf": "Reliability" + "subcategory": "Defender for Azure SQL", + "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", + "waf": "Security" }, { - "category": "BC and DR", - "checklist": "Azure App Service Review", - "description": "Enabling 'Always On' for Function Apps ensures that the app does not go idle, maintaining its availability and responsiveness at all times.", - "guid": "c7b5f3d1-0569-4fd2-9f32-c0b64e9c0c5e", - "link": "https://learn.microsoft.com/azure/azure-functions/dedicated-plan#always-on", - "service": "App Services", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQLDB vulnerability assessment is a service that provides visibility into your security state. Vulnerability assessment includes actionable steps to resolve security issues and enhance your database security. It can help you to monitor a dynamic database environment where changes are difficult to track and improve your SQL security posture.", + "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", "services": [ - "AppSvc" + "Monitor", + "SQL", + "Defender" ], - "severity": "Medium", - "subcategory": "High Availability", - "text": "Ensure 'Always On' is enabled for Function Apps running on App Service plans to prevent idling and ensure continuous availability.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Vulnerability Assessment", + "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", + "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure App Service Review", - "description": "Health checks monitor the health of App Service instances, enabling automatic replacement of unhealthy instances to maintain high availability.", - "guid": "a3b4d5f6-758c-4f9d-9e1a-d7c6b7e8f9ab", - "link": "https://learn.microsoft.com/azure/app-service/monitor-instances-health-check", - "service": "App Services", + "category": "Defender", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Microsoft Defender for Cloud provides vulnerability assessment for your Azure SQL Databases. Vulnerability assessment scans your databases for software vulnerabilities and provides a list of findings. You can use the findings to remediate software vulnerabilities and disable findings.", + "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", "services": [ - "AppSvc", - "Monitor" + "SQL", + "Defender" ], - "severity": "Medium", - "subcategory": "Monitoring", - "text": "Monitor App Service instances using Health checks to detect unhealthy instances and automatically replace them.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Vulnerability Assessment", + "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", + "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure App Service Review", - "guid": "c7d3e5f9-a19c-4833-8ca6-1dcb0128e129", - "link": "https://learn.microsoft.com/azure/azure-monitor/app/availability-overview", - "service": "App Services", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Always Encrypted with Secure Enclaves expands confidential computing capabilities of Always Encrypted by enabling in-place encryption and richer confidential queries. Always Encrypted with Secure Enclaves addresses these limitations by allowing some computations on plaintext data inside a secure enclave on the server side. Usage of this feature is recommended for the cases where you need to limit administrator access and need your queries to support more than equality matching of encrypted columns.", + "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", "services": [ - "AppSvc", - "Monitor" + "SQL" ], "severity": "Medium", - "subcategory": "Monitoring", - "text": "Monitor availability and responsiveness of web app or website using Application Insights availability tests, ensuring proactive detection of performance issues and downtime.", - "waf": "Reliability" + "subcategory": "Always Encrypted", + "text": "If protecting sensitive PII data from admin users is a key requirement, but Column Encryption limitations cannot be tolerated, consider the adoption of Always Encrypted with Secure Enclaves", + "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure App Service Review", - "guid": "b4e3f2d5-a5c6-4d7e-8b2f-c5d9e7a8f0ea", - "link": "https://learn.microsoft.com/azure/azure-monitor/app/availability-standard-tests", - "service": "App Services", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "With Azure SQL Database, you can apply symmetric encryption to a column of data by using Transact-SQL. This approach is called column encryption, because you can use it to encrypt specific columns with different encryption keys. Doing so gives you more granular encryption capability than TDE, which encrypts data in pages. Using Always Encrypted to ensure sensitive data isn't exposed in plaintext in Azure SQL Database or SQL Managed Instance, even in memory/in use. Always Encrypted protects the data from Database Administrators (DBAs) and cloud admins (or bad actors who can impersonate high-privileged but unauthorized users) and gives you more control over who can access your data.", + "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", "services": [ - "AppSvc", - "Monitor" + "Storage", + "SQL", + "AKV" ], "severity": "Low", - "subcategory": "Monitoring", - "text": "Use Application Insights Standard test to monitor availability and responsiveness of web app or website", - "waf": "Reliability" + "subcategory": "Column Encryption", + "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption", + "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Azure Key Vault ensures secrets are encrypted, securely stored, and accessed only by authorized applications. It supports audit logging, and secret versioning, and reduces the risk of accidental exposure of sensitive information.", - "guid": "834ac932-223e-4ce8-8b12-3071a5416415", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", - "service": "App Services", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Enabled by default, Transparent data encryption (TDE) helps to protect the database files against information disclosure by performing real-time encryption and decryption of the database, associated backups, and transaction log files 'at rest', without requiring changes to the application.", + "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "services": [ - "AKV", - "AppSvc" + "Storage", + "SQL", + "Backup" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Use Azure Key Vault to store any secrets the application needs. Key Vault provides a secure, managed, and audited environment for storing secrets, and integrates seamlessly with App Service via App Service Key Vault References for enhanced security.", + "subcategory": "Transparent Data Encryption", + "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Managed Identity eliminates the need for hard-coded credentials by allowing App Service to authenticate to Azure Key Vault securely. This reduces the risk of credential exposure and simplifies secret management for enhanced security.", - "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", - "service": "App Services", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "If separation of duties in the management of keys and data within the organization is required, leverage Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) for your Azure SQLDB and use Azure Key Vault to store (refer to its checklist). Leverage this feature when you have strict security requirements which cannot be met by the managed service keys.", + "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", "services": [ - "AKV", - "AppSvc", - "Entra" + "SQL", + "AKV" ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Use Managed Identity to securely connect to Azure Key Vault for accessing secrets, through App Service Key Vault References.", + "severity": "Medium", + "subcategory": "Transparent Data Encryption", + "text": "Use customer-managed keys (CMK) in Azure Key Vault (AKV) if you need increased transparency and granular control over the TDE protection", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Storing TLS certificates in Azure Key Vault enhances security by providing centralized, secure management and automated renewal of certificates. This reduces the risk of manual handling errors and certificate expiration.", - "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", - "service": "App Services", + "category": "Encryption", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The minimal Transport Layer Security (TLS) version setting allows customers to choose which version of TLS their SQL database uses. It's possible to change the minimum TLS version by using the Azure portal, Azure PowerShell, and the Azure CLI.", + "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", "services": [ - "AKV", - "AppSvc", - "Entra" + "SQL" ], "severity": "High", - "subcategory": "Data Protection", - "text": "Use Azure Key Vault to securely store and manage TLS certificates for App Service.", + "subcategory": "Transport Layer Security", + "text": "Enforce minimum TLS version to the latest available", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "To minimize exposure and improve security, isolate systems processing sensitive data. Leverage separate App Service Plans or App Service Environments for isolation, and use different subscriptions or management groups to enforce stricter boundaries and governance.", - "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", - "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", - "service": "App Services", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Use Azure Active Directory (Azure AD) authentication for centralized identity management. Use SQL Authentication only if really necessary and document as exceptions.", + "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", "services": [ - "AppSvc", - "Subscriptions" + "SQL", + "Entra" ], "severity": "Medium", - "subcategory": "Data Protection", - "text": "Isolate systems that process sensitive information using separate App Service Plans, App Service Environments (ASE), and consider different subscriptions or management groups for enhanced security.", + "subcategory": "Azure Active Directory", + "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Local disks on App Service are not encrypted and sensitive data should not be stored on those. (For example: D:\\\\Local and %TMP%).", - "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", - "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", - "service": "App Services", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Using Azure AD groups simplifies permission management and both the group owner, and the resource owner can add/remove members to/from the group. Create a separate group for Azure AD administrators for each logical server. Monitor Azure AD group membership changes using Azure AD audit activity reports.", + "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", "services": [ - "AppSvc", - "TrafficManager" + "Monitor", + "SQL", + "Entra" ], "severity": "Medium", - "subcategory": "Data Protection", - "text": "Do not store sensitive data on local disk", + "subcategory": "Azure Active Directory", + "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Use Microsoft Entra ID or B2C for secure user authentication and Single Sign-On (SSO) across applications. Integrate using the built-in App Service Authentication/Authorization feature for streamlined security and compliance with modern authentication protocols like OpenID Connect.", - "guid": "919ca0b2-c121-459e-814b-933df574eccc", - "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", - "service": "App Services", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Ensure that distinct system and user assigned managed identities, that are dedicated to the function, with least permissions assigned, are used for communication from Azure services and applications to the Azure SQLDB databases.", + "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", "services": [ - "ACR", - "AppSvc", + "SQL", "Entra" ], "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Use Microsoft Entra ID or B2C for secure authentication and Single Sign-On (SSO).", + "subcategory": "Azure Active Directory", + "text": "Minimize the use of password-based authentication for applications", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Ensure all code deployments to App Service originate from a controlled, secured environment, such as a well-managed DevOps pipeline. This practice mitigates the risk of deploying unauthorized or malicious code by enforcing version control, code verification, and secure hosting.", - "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", - "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", - "service": "App Services", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "System or User assigned managed identities enable Azure SQLDB to authenticate to other cloud services (e.g. Azure Key Vault) without storing credentials in code. Once enabled, all necessary permissions can be granted via Azure role-based-access-control to the specific Azure SQLDB instance. Do not share user assigned managed identities across multiple services if not strictly required.", + "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "services": [ - "AppSvc", - "Entra" + "ACR", + "RBAC", + "Entra", + "SQL", + "AKV" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Deploy code to App Service from a trusted and secure environment.", + "severity": "Low", + "subcategory": "Managed Identities", + "text": "Assign Azure SQL Database a managed identity for outbound resource access", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Disable basic authentication for FTP/FTPS and WebDeploy/SCM to enhance security by enforcing Microsoft Entra ID secured endpoints for deployment. This ensures that only authenticated users using Microsoft Entra ID credentials can access deployment services, including the SCM site.", - "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", - "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", - "service": "App Services", + "category": "Identity", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Use an Azure AD integrated authentication that eliminates the use of passwords. Password-based authentication methods are a weaker form of authentication. Credentials can be compromised or mistakenly given away. Use single sign-on authentication using Windows credentials. Federate the on-premises AD domain with Azure AD and use integrated Windows authentication (for domain-joined machines with Azure AD).", + "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", "services": [ - "AppSvc", + "SQL", "Entra" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable basic authentication for FTP/FTPS and WebDeploy/SCM.", + "severity": "Medium", + "subcategory": "Passwords", + "text": "Minimize the use of password-based authentication for users", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Wherever possible, use Managed Identity to securely connect to Microsoft Entra ID-secured resources without storing credentials. If this is not feasible, store secrets in Azure Key Vault and access them using Managed Identity to maintain security and reduce the risk of credential exposure.", - "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", - "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", - "service": "App Services", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Confidential Ledger is one of the supported store, it can be used and supports automatic generation and storage of database digests. Azure Ledger provides advanced security features like Blockchain Ledger Proof and Confidential Hardware Enclaves. Use it only if advanced security features are required, otherwise revert to Azure storage.", + "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", "services": [ - "AKV", - "AppSvc", - "Entra" + "Storage", + "SQL" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identity to connect to Microsoft Entra ID secured resources.", + "severity": "Medium", + "subcategory": "Database Digest", + "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "When using images stored in Azure Container Registry, pull these images using a Managed Identity to avoid storing credentials. This ensures secure access to container images and reduces the risk of credential exposure.", - "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", - "service": "App Services", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Blob Storage with Immutable Storage feature can be used and supports automatic generation and storage of database digests. To prevent tampering of your digest files, configure and lock a retention policy for your container.", + "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", "services": [ - "ACR", - "AppSvc", - "Entra" + "Storage", + "SQL", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Pull container images from Azure Container Registry using a Managed Identity.", + "severity": "Medium", + "subcategory": "Database Digest", + "text": "If Azure storage account is used to store database digests, ensure security is properly configured", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Configure diagnostic settings to send telemetry and security logs (including HTTP, platform, and audit logs) to Log Analytics. Centralized logging enhances monitoring, threat detection, and compliance reporting.", - "guid": "47768314-c115-4775-a2ea-55b46ad48408", - "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", - "service": "App Services", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Ledger provides a form of data integrity called forward integrity, which provides evidence of data tampering on data in your ledger tables. The database verification process takes as input one or more previously generated database digests. It then recomputes the hashes stored in the database ledger based on the current state of the ledger tables. If the computed hashes don't match the input digests, the verification fails. The failure indicates that the data has been tampered with. The verification process reports all inconsistencies that it detects.", + "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", "services": [ - "AppSvc", - "Monitor", - "Entra" + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Send App Service runtime and security logs to Log Analytics for centralized monitoring and alerting.", + "subcategory": "Integrity", + "text": "Schedule the Ledger verification process regularly to verify data integrity", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Set up a diagnostic setting to send the activity log to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the App Service resource itself.", - "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", - "service": "App Services", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The Ledger feature provides tamper-evidence capabilities in your database. You can cryptographically attest to other parties, such as auditors or other business parties, that your data hasn't been tampered with. Ledger helps protect data from any attacker or high-privileged user, including database administrators (DBAs), system administrators, and cloud administrators.", + "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", "services": [ - "AppSvc", - "Monitor", - "Entra" + "SQL" ], "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Send App Service activity logs to Log Analytics", + "subcategory": "Ledger", + "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Use regional VNet integration, Network Security Groups (NSGs), and User-Defined Routes (UDRs) to control outbound network access. Route traffic through a Network Virtual Appliance (NVA), such as Azure Firewall, and monitor firewall logs to ensure traffic is properly controlled and secure.", - "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", - "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", - "service": "App Services", + "category": "Ledger", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Depending on the type of tampering, there are cases where you can repair the ledger without losing data. In the article contained in the --More Info-- column, different scenarios and recovery techniques are described.", + "guid": "804fc554-6554-4842-91c1-713b32f99902", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", "services": [ - "AppSvc", - "Monitor", - "NVA", - "Firewall", - "VNet" + "SQL" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Control outbound network access for App Service using VNet integration, NSGs, UDRs, and firewalls.", + "subcategory": "Recovery", + "text": "Prepare a response plan to investigate and repair a database after a tampering event", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Provide a stable outbound IP by using VNet integration with a NAT Gateway or Network Virtual Appliance (NVA) like Azure Firewall. This enables the receiving party to allow-list based on IP, if necessary. For communications with Azure services, use mechanisms like Service Endpoints or private endpoints to avoid relying on static IPs, ensuring secure and efficient connectivity.", - "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", - "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", - "service": "App Services", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database Auditing tracks database events and writes them to an audit log in your Azure storage account. Auditing helps you understand database activity and gain insight into discrepancies and anomalies that could indicate business concerns or suspected security violations as well as helps you meet regulatory compliance. By default auditing policy includes all actions (queries, stored procedures and successful and failed logins) against the databases, which may result in high volume of audit logs. It's recommended for customers to configure auditing for different types of actions and action groups using PowerShell.", + "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "services": [ - "AppSvc", - "NVA", - "Firewall", "Storage", - "VNet", - "PrivateLink" + "SQL", + "AzurePolicy" + ], + "severity": "Medium", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", + "waf": "Security" + }, + { + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database Auditing logs can be written to external storage accounts, Log Analytics workspace or Event Hub. Be sure to protect the target repository using backups and secured configuration. Use Azure SQL Database Managed Identity to access the storage and set an explicit retention period. Do not grant permissions to administrators to the audit log repository. Use a different target storage for --Enabling Auditing of Microsoft support operations--. ", + "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "services": [ + "EventHubs", + "Backup", + "Storage", + "Entra", + "Monitor", + "SQL" ], "severity": "Low", - "subcategory": "Network Security", - "text": "Ensure a stable IP for outbound communications by using VNet NAT Gateway or Azure Firewall.", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Control inbound network access by configuring App Service Access Restrictions, Service Endpoints, or Private Endpoints. Ensure appropriate restrictions are set for both the web app and the SCM (deployment) site to limit unauthorized access and enhance security.", - "guid": "0725769e-e669-41a4-a34a-c932223ece80", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", - "service": "App Services", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The Azure Monitor activity log is a platform log in Azure that provides insight into subscription-level events. The activity log includes information like when a resource is modified. It is recommended to send this activity log to the same external storage repository as the Azure SQL Database Audit Log (storage account, Log Analytics workspace, Event Hub).", + "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "PrivateLink", - "AppSvc" + "EventHubs", + "Storage", + "Monitor", + "SQL", + "Subscriptions" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Control inbound network access using Access Restrictions, Service Endpoints, or Private Endpoints.", + "severity": "Medium", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Protect App Service from malicious inbound traffic by deploying a Web Application Firewall (WAF) using Azure Application Gateway or Azure Front Door. Ensure WAF logs are monitored regularly to detect and respond to security threats.", - "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", - "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", - "service": "App Services", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR). Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", + "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "services": [ - "AppSvc", "Monitor", - "AppGW", - "WAF", - "FrontDoor" + "SQL" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Use a Web Application Firewall (WAF) in front of App Service.", + "severity": "Medium", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "To prevent the Web Application Firewall (WAF) from being bypassed, lock down access to App Service by using Access Restrictions, Service Endpoints, and Private Endpoints. This ensures that all traffic is routed through the WAF, providing a secure front layer of protection.", - "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", - "service": "App Services", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR), which can be used to set up custom threat detections. Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", + "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "PrivateLink", - "AppSvc", - "WAF" + "Monitor", + "SQL" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Ensure the WAF cannot be bypassed by securing access to App Service.", + "severity": "Medium", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Ensure that the minimum TLS policy is set to 1.2 or higher, with a preference for TLS 1.3, to enhance security through stronger encryption protocols. TLS 1.3 provides additional security improvements and faster handshake times, reducing vulnerabilities associated with older versions.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", - "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", - "service": "App Services", + "category": "Logging", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Security Operation Center (SOC) team should create an incident response plan (playbooks or manual responses) to investigate and mitigate tampering, malicious activities, and other anomalous behaviors.", + "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "services": [ - "AppSvc", - "AzurePolicy" + "EventHubs", + "SQL" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Set minimum TLS policy to 1.2 or higher, preferably 1.3, in App Service configuration.", + "subcategory": "SIEM/SOAR", + "text": "Ensure that you have response plans for malicious or aberrant audit logging events", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Configure App Service to enforce HTTPS-only, automatically redirecting all HTTP traffic to HTTPS. Additionally, implement HTTP Strict Transport Security (HSTS) in your code or via a Web Application Firewall (WAF) to ensure browsers only access the site over HTTPS, enhancing security by preventing downgrade attacks.", - "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", - "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "When you create a logical server from the Azure portal for Azure SQL Database, the result is a public endpoint that is visible and reachable over the public network (Public Access). You can then limit connectivity based on firewall rules and Service Endpoint. You can also configure private connectivity only limiting connections to internal networks using Private Endpoint (Private Access). Private Access using Private Endpoint should be the default unless a business case or performance/technical reason applies that cannot support it. Usage of Private Endpoints has performance implications that need to be considered and assessed.", + "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "services": [ - "AppSvc", - "WAF" + "PrivateLink", + "SQL" ], "severity": "High", - "subcategory": "Network Security", - "text": "Use HTTPS only and consider enabling HTTP Strict Transport Security (HSTS).", + "subcategory": "Connectivity", + "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Do not use wildcards (*) in your CORS configuration, as this permits unrestricted access from any origin, compromising security. Instead, explicitly specify trusted origins that are allowed to access the service, ensuring controlled access.", - "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", - "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "IMPORTANT: Connections to private endpoint only support Proxy as the connection policy. When using private endpoints connections are proxied via the Azure SQL Database gateway to the database nodes. Clients will not have a direct connection.", + "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", "services": [ - "Storage", - "AppSvc" + "PrivateLink", + "SQL", + "AzurePolicy" ], - "severity": "High", - "subcategory": "Network Security", - "text": "Avoid using wildcards for CORS; specify allowed origins explicitly.", + "severity": "Low", + "subcategory": "Connectivity", + "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Remote debugging should not be enabled in production as it opens additional ports, increasing the attack surface. Although App Service automatically turns off remote debugging after 48 hours, it is recommended to disable it manually in production to maintain a secure environment.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", - "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", - "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers. If you select this option, make sure that your login and user permissions limit access to authorized users only. If not strictly required, keep this setting to OFF.", + "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "services": [ - "AppSvc" + "SQL", + "Subscriptions" ], "severity": "High", - "subcategory": "Network Security", - "text": "Turn off remote debugging in production environments.", + "subcategory": "Connectivity", + "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Enable Defender for App Service. This (amongst other threats) detects communications to known malicious IP addresses. Review the recommendations from Defender for App Service as part of your operations.", - "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure SQL Database has a new built-in feature that allows native integration with external REST endpoints. This means that integration of Azure SQL Database with Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management and in general any REST or even GraphQL endpoint. If not properly restricted, code inside an Azure SQL Database database could leverage this mechanism to exfiltrate data. If not strictly required, it is recommended to block or restrict this feature using Outbound Firewall Rules.", + "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", "services": [ - "Defender", - "AppSvc" + "EventHubs", + "SQL", + "APIM" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Enable Defender for Cloud - Defender for App Service", + "subcategory": "Outbound Control", + "text": "Block or restrict outbound REST API calls to external endpoints", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Azure provides DDoS Basic protection on its network, which can be improved with intelligent DDoS Standard capabilities which learns about normal traffic patterns and can detect unusual behavior. DDoS Standard applies to a Virtual Network so it must be configured for the network resource in front of the app, such as Application Gateway or an NVA.", - "guid": "223ece80-b123-4071-a541-6415833ea3ad", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Outbound firewall rules limit network traffic from the Azure SQL Database logical server to a customer defined list of Azure Storage accounts and Azure SQL Database logical servers. Any attempt to access storage accounts or databases not in this list is denied.", + "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", "services": [ - "AppSvc", - "NVA", - "WAF", - "EventHubs", - "AppGW", - "VNet", - "DDoS" + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Enable DDOS Protection Standard on the WAF VNet", + "subcategory": "Outbound Control", + "text": "If outbound network access is required, it is recommended to configure outbound networking restrictions using built-in Azure SQL Database control feature", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "When using images stored in Azure Container Registry, ensure they are pulled over a virtual network by using a private endpoint and configuring the app setting 'WEBSITE_PULL_IMAGE_OVER_VNET'. This ensures secure communication between App Service and the registry, preventing exposure to the public internet.", - "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Private Endpoint is created inside a subnet in an Azure Virtual Network. Proper security configuration must be applied also to the containing network environment, including NSG/ASG, UDR, firewall, monitoring and auditing.", + "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "services": [ - "ACR", - "AppSvc", "PrivateLink", - "VNet" + "Firewall", + "Monitor", + "VNet", + "SQL" ], "severity": "Medium", - "subcategory": "Network Security", - "text": "Pull container images over a Virtual Network from Azure Container Registry.", + "subcategory": "Private Access", + "text": "If Private Access connectivity is used, ensure that you are using the Private Endpoint, Azure Virtual Network, Azure Firewall, and Azure Network Security Group checklists", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Perform a penetration test on the web application in accordance with Azure's penetration testing rules of engagement. This helps identify vulnerabilities and security weaknesses that can be addressed before they are exploited.", - "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", - "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "When adding a Private Endpoint connection, public routing to your logical server isn't blocked by default. In the --Firewall and virtual networks-- pane, the setting --Deny public network access-- is not selected by default. To disable public network access, ensure that you select --Deny public network access--.", + "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "services": [ - "AppSvc" + "PrivateLink", + "VNet", + "SQL" + ], + "severity": "High", + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Network Security Group (NSG) and Application Security Group (ASG) can be now applied to subnet containing Private Endpoints to restrict connections to Azure SQLDB based on internal source IP ranges.", + "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", + "services": [ + "PrivateLink", + "VNet", + "SQL" ], "severity": "Medium", - "subcategory": "Penetration Testing", - "text": "Conduct a penetration test on the web application.", + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, apply NSG and eventually ASG to limit incoming source IP address ranges", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Ensure that only trusted code, which has been validated and scanned for vulnerabilities, is deployed to production following DevSecOps practices. This minimizes the risk of introducing security vulnerabilities into the application environment.", - "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. Applications and tools that are in the same or peered virtual network in the same region could access it directly. Applications and tools that are in different region could use virtual-network-to-virtual-network connection or ExpressRoute circuit peering to establish connection. Customer should use Network Security Groups (NSG), and eventually internal firewalls, to restrict access over port 1433 only to resources that require access to a managed instance.", + "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", "services": [ - "AppSvc" + "ExpressRoute", + "VNet", + "SQL" ], "severity": "Medium", - "subcategory": "Vulnerability Management", - "text": "Deploy validated and vulnerability-scanned code.", + "subcategory": "Private Access", + "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet", "waf": "Security" }, { - "category": "Security", - "checklist": "Azure App Service Review", - "description": "Ensure that the latest versions of supported platforms, programming languages, protocols, and frameworks are used. Regular updates mitigate the risk of security vulnerabilities and ensure compatibility with security patches.", - "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", - "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Azure Virtual Network Service Endpoint is preferred solution if you want to establish a direct connection to the Azure SQL Database backend nodes using Redirect policy. This will allow access in high performance mode and is the recommended approach from a performance perspective.", + "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", "services": [ - "AppSvc" + "VNet", + "SQL", + "AzurePolicy" ], "severity": "High", - "subcategory": "Vulnerability Management", - "text": "Use up-to-date platforms, languages, protocols and frameworks", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", "waf": "Security" }, { - "category": "Operations", - "checklist": "Azure App Service Review", - "description": "Leverage Auto-Healing in Azure App Service to automatically restart instances or trigger custom actions based on pre-defined failure conditions like memory thresholds, HTTP errors, or specific event logs.", - "guid": "60b3a935-33e5-45c9-87c7-53882e395b46", - "link": "https://learn.microsoft.com/azure/app-service/overview-diagnostics", - "service": "App Services", + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The Azure SQL Database firewall allows you to specify IP address ranges from which communications are accepted. This approach is fine for stable IP addresses that are outside the Azure private network.", + "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "services": [ - "AppSvc" + "Storage", + "SQL" ], "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Auto-Healing with custom rules to restart App Service instances automatically when failures occur.", - "waf": "Reliability" - }, + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "We recommend that you use database-level IP firewall rules whenever possible. This practice enhances security and makes your database more portable. Use server-level IP firewall rules for administrators. Also use them when you have many databases that have the same access requirements, and you don't want to configure each database individually.", + "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", + "services": [ + "Storage", + "SQL" + ], + "severity": "Low", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used and controlled by Azure SQL Database firewall rules, use database-level over server-level IP rules", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. The Managed Instance public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. If company policy disallows the use of public endpoints, use Azure Policy to prevent enabling public endpoints in the first place.", + "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "services": [ + "VNet", + "SQL", + "AzurePolicy" + ], + "severity": "High", + "subcategory": "Public Access", + "text": "Do not enable Azure SQL Managed Instance public endpoint", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "A Managed Instance (SQL MI) public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. In this case, it is recommended to apply a Network Security Groups (NSG) to restrict access to port 3342 only to trusted source IP addresses.", + "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "services": [ + "VNet", + "SQL" + ], + "severity": "High", + "subcategory": "Public Access", + "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", + "waf": "Security" + }, + { + "category": "Privileged Access", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Most operations, support, and troubleshooting performed by Microsoft personnel and sub-processors do not require access to customer data. In those rare circumstances where such access is required, Customer Lockbox for Microsoft Azure provides an interface for customers to review and approve or reject customer data access requests. In support scenarios where Microsoft needs to access customer data, Azure SQL Database supports Customer Lockbox to provide an interface for you to review and approve or reject customer data access requests.", + "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "services": [ + "SQL" + ], + "severity": "Low", + "subcategory": "Lockbox", + "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", + "waf": "Security" + }, + { + "category": "Privileged Access", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "The principle of least privilege states that users shouldn't have more privileges than needed to complete their tasks. High-privileged database and server users can perform many configuration and maintenance activities on the database and can also drop databases in Azure SQL instance. Tracking database owners and privileged accounts is important to avoid having excessive permission.", + "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", + "services": [ + "SQL" + ], + "severity": "Medium", + "subcategory": "Permissions", + "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", + "waf": "Security" + }, + { + "category": "Privileged Access", + "checklist": "Azure SQLDB Security Checklist (Preview)", + "description": "Identities (both Users and SPNs) should be scoped to the least amount of access needed to perform the function. A higher number of tightly scoped SPNs should be used, instead of having one SPN with multiple sets of unrelated permissions. For example, if there are three external web applications hosted on-prem that make queries to the Azure SQL Database, they should not all use the same SPN for these activities. Instead, they should each have their own tightly scoped SPN.", + "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", + "services": [ + "SQL", + "Entra" + ], + "severity": "Low", + "subcategory": "Permissions", + "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", + "waf": "Security" + }, + { + "category": "BC and DR", + "checklist": "Azure App Service Review", + "description": "Leverage zone-redundancy to ensure high availability in the event of zone-level failures. Use Premium V2/V3 or Isolated v2 tiers, which provide support for zone-redundant deployments and ensure minimal downtime during disasters.", + "guid": "b32e1aa1-4813-4602-88fe-27ca2891f421", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/app-service-web-app/zone-redundant?source=recommendations", + "service": "App Services", + "services": [ + "AppSvc" + ], + "severity": "Low", + "subcategory": "High Availability", + "text": "Implement a baseline highly available zone-redundant web application architecture. Ensure your Azure App Service is on Premium V2/V3 or Isolated v2 tiers for zone-redundant support.", + "waf": "Reliability" + }, + { + "category": "BC and DR", + "checklist": "Azure App Service Review", + "description": "Leverage staging slots for zero-downtime deployments and automated backups to ensure disaster recovery. Choose the appropriate tier (Standard or Premium) based on the number of slots and disaster recovery requirements.", + "graph": "resources | where type =~ 'microsoft.web/serverfarms' | extend compliant = (sku.tier == 'Premium' or sku.tier == 'Standard') | distinct id,compliant", + "guid": "e4b31c6a-2e3f-4df1-8e8b-9c3aa5a27820", + "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", + "service": "App Services", + "services": [ + "AppSvc", + "ASR", + "Backup" + ], + "severity": "Medium", + "subcategory": "High Availability", + "text": "Use Premium and Standard tiers for staging slots and automated backups. Align your backup retention period with disaster recovery needs.", + "waf": "Reliability" + }, + { + "category": "BC and DR", + "checklist": "Azure App Service Review", + "description": "Availability Zones provide physical isolation across datacenters in a region, reducing downtime during outages. Verify your region supports Availability Zones and use Premium V2/V3 tiers for zone-redundant deployments.", + "guid": "a7e2e6c2-491f-4fa4-a82b-521d0bc3b202", + "link": "https://learn.microsoft.com/azure/reliability/migrate-app-service", + "service": "App Services", + "services": [ + "AppSvc", + "ACR" + ], + "severity": "High", + "subcategory": "High Availability", + "text": "Leverage Availability Zones where regionally applicable (Premium V2/V3 tier required). Check region support for Availability Zones.", + "waf": "Reliability" + }, { "category": "Operations", "checklist": "Azure App Service Review", - "description": "Configure Azure Monitor alerts based on Application Insights metrics for response times, failure rates, and overall availability. Alerts help detect issues proactively and reduce mean-time-to-recovery (MTTR).", - "guid": "e52e4514-02a7-4e81-a98e-88ce1b18e557", - "link": "https://learn.microsoft.com/azure/azure-monitor/app/alerts", + "description": "Enable health checks to detect unhealthy instances in real-time and automatically replace them to maintain high availability and application reliability.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.HealthCheckPath != '') | distinct id,compliant", + "guid": "1275e4a9-7b6a-43c3-a9cd-5ee18d8995ad", + "link": "https://learn.microsoft.com/azure/app-service/monitor-instances-health-check", "service": "App Services", "services": [ "AppSvc", @@ -6748,574 +7193,1185 @@ ], "severity": "Medium", "subcategory": "Monitoring", - "text": "Set up alerts for critical Application Insights metrics, such as response time and failure rates.", + "text": "Implement health checks to monitor and detect issues with App Service instances. Health checks enable automatic instance replacement on failure.", "waf": "Reliability" }, { - "category": "Governance and Security", + "category": "Operations", "checklist": "Azure App Service Review", - "description": "Use Azure Policy to enforce security, compliance, and governance configurations for App Service. Policies can ensure that critical settings such as TLS versions, backup configurations, and network restrictions are enforced across all App Service instances.", - "guid": "361e886f-ca40-4ead-a8e9-1379c642ae9c", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "description": "Follow best practices for configuring backups and restores in Azure App Service and ASE to guarantee data availability and ensure recovery during disaster scenarios.", + "guid": "35a91c5d-4ad6-4d9b-8e0f-c47db9e6d1e7", + "link": "https://learn.microsoft.com/azure/app-service/manage-backup", "service": "App Services", "services": [ - "ACR", "AppSvc", - "Backup", - "AzurePolicy" + "Backup" ], "severity": "High", - "subcategory": "Compliance", - "text": "Apply Azure Policy to enforce compliance across App Service configurations.", - "waf": "Governance" + "subcategory": "Multi-tenant service", + "text": "Refer to backup and restore best practices for Azure App Service and App Service Environments (ASE) to ensure data availability and recovery.", + "waf": "Reliability" }, { - "category": "Cost Governance", + "category": "BC and DR", "checklist": "Azure App Service Review", - "description": "Leverage Azure Cost Management to track and forecast App Service expenses. Set up alerts for budget thresholds to avoid overspending, and optimize costs based on resource utilization trends.", - "guid": "42eb48f0-28ff-497c-b2c0-a8fa1f989832", - "link": "https://learn.microsoft.com/azure/cost-management-billing/", + "description": "Ensure high availability by incorporating scaling, fault tolerance, monitoring, and zone redundancy into your App Service architecture. Leverage health checks and availability zones to maintain uptime.", + "guid": "e68cd0ec-afc6-4bd8-a27f-7860ad9a0db2", + "link": "https://learn.microsoft.com/azure/architecture/framework/services/compute/azure-app-service/reliability", "service": "App Services", "services": [ - "Cost", "AppSvc", "Monitor" ], - "severity": "Low", - "subcategory": "Cost Monitoring", - "text": "Monitor App Service costs using Azure Cost Management and create cost alerts.", - "waf": "Cost" + "severity": "High", + "subcategory": "High Availability", + "text": "Implement Azure App Service reliability best practices, including auto-scaling, fault tolerance, health checks, and zone redundancy.", + "waf": "Reliability" }, { - "category": "Cost Governance", + "category": "BC and DR", "checklist": "Azure App Service Review", - "description": "If you have predictable and steady usage of App Service, purchasing Reserved Instances can significantly reduce long-term costs. Commit to one or three years for lower pricing compared to pay-as-you-go.", - "guid": "e489221b-487e-48a3-aaab-48e3d205ca12", - "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/", + "description": "Prepare for disaster recovery by implementing region failover strategies. Utilize active-active and active-passive configurations, automated failover, and Infrastructure as Code (IaC) for seamless failover during outages.", + "guid": "bd2a865c-0835-4418-bb58-4df91a5a9b3f", + "link": "https://learn.microsoft.com/azure/app-service/manage-disaster-recovery#recover-app-content-only", "service": "App Services", "services": [ - "Cost", - "Storage", "AppSvc", - "ARS" + "ASR" ], - "severity": "Medium", - "subcategory": "Cost Optimization", - "text": "Purchase reserved instances for App Service plans to optimize long-term costs.", - "waf": "Cost" + "severity": "Low", + "subcategory": "High Availability", + "text": "Familiarize with App Service region failover, including active-active and active-passive configurations, automated failover, and IaC deployment.", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "d7e47431-76c8-4bdb-b55b-ce619e8a03f9", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-service-principal?pivots=aro-azurecli", + "category": "BC and DR", + "checklist": "Azure App Service Review", + "description": "Azure App Service offers built-in reliability features, including scaling, fault tolerance, and service-level agreements (SLAs). Leverage these features to maintain consistent performance during outages.", + "guid": "f3d2f1e4-e6d4-4b7a-a5a5-e2a9b2c6f293", + "link": "https://learn.microsoft.com/azure/reliability/reliability-app-service", + "service": "App Services", "services": [ - "RBAC", - "Entra" + "AppSvc" ], "severity": "High", - "subcategory": "Identity", - "text": "Create a service principal and its role assignments before creating the ARO clusters.", - "waf": "Security" + "subcategory": "High Availability", + "text": "Familiarize with reliability support in Azure App Service, including scaling options, SLAs, and automated recovery mechanisms.", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "7879424d-6267-486d-90b9-6c97be985190", - "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", + "category": "BC and DR", + "checklist": "Azure App Service Review", + "description": "Enabling 'Always On' for Function Apps ensures that the app does not go idle, maintaining its availability and responsiveness at all times.", + "guid": "c7b5f3d1-0569-4fd2-9f32-c0b64e9c0c5e", + "link": "https://learn.microsoft.com/azure/azure-functions/dedicated-plan#always-on", + "service": "App Services", "services": [ - "Entra" + "AppSvc" ], - "severity": "High", - "subcategory": "Identity", - "text": "Use AAD to authenticate users in your ARO cluster.", - "waf": "Security" + "severity": "Medium", + "subcategory": "High Availability", + "text": "Ensure 'Always On' is enabled for Function Apps running on App Service plans to prevent idling and ensure continuous availability.", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", - "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "category": "Operations", + "checklist": "Azure App Service Review", + "description": "Health checks monitor the health of App Service instances, enabling automatic replacement of unhealthy instances to maintain high availability.", + "guid": "a3b4d5f6-758c-4f9d-9e1a-d7c6b7e8f9ab", + "link": "https://learn.microsoft.com/azure/app-service/monitor-instances-health-check", + "service": "App Services", "services": [ - "Entra" + "AppSvc", + "Monitor" ], "severity": "Medium", - "subcategory": "Identity", - "text": "When using AAD authentication, remove kubeadmin user from the cluster.", - "waf": "Security" + "subcategory": "Monitoring", + "text": "Monitor App Service instances using Health checks to detect unhealthy instances and automatically replace them.", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "483835c9-86bb-4291-8155-a11475e39f54", - "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", + "category": "Operations", + "checklist": "Azure App Service Review", + "guid": "c7d3e5f9-a19c-4833-8ca6-1dcb0128e129", + "link": "https://learn.microsoft.com/azure/azure-monitor/app/availability-overview", + "service": "App Services", "services": [ - "RBAC", - "Entra" + "AppSvc", + "Monitor" ], - "severity": "High", - "subcategory": "Identity", - "text": "Define OpenShift projects to restrict RBAC privilege and isolate workloads in your cluster.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Monitoring", + "text": "Monitor availability and responsiveness of web app or website using Application Insights availability tests, ensuring proactive detection of performance issues and downtime.", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", - "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", + "category": "Operations", + "checklist": "Azure App Service Review", + "guid": "b4e3f2d5-a5c6-4d7e-8b2f-c5d9e7a8f0ea", + "link": "https://learn.microsoft.com/azure/azure-monitor/app/availability-standard-tests", + "service": "App Services", "services": [ - "RBAC", - "Entra" + "AppSvc", + "Monitor" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Define the required RBAC roles in OpenShift are scoped to either a project or a cluster.", - "waf": "Security" + "severity": "Low", + "subcategory": "Monitoring", + "text": "Use Application Insights Standard test to monitor availability and responsiveness of web app or website", + "waf": "Reliability" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Azure Key Vault ensures secrets are encrypted, securely stored, and accessed only by authorized applications. It supports audit logging, and secret versioning, and reduces the risk of accidental exposure of sensitive information.", + "guid": "834ac932-223e-4ce8-8b12-3071a5416415", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "service": "App Services", "services": [ - "AKV", - "Entra" + "AppSvc", + "AKV" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Minimize the number of users who have administrator rights and secrets access.", + "severity": "High", + "subcategory": "Data Protection", + "text": "Use Azure Key Vault to store any secrets the application needs. Key Vault provides a secure, managed, and audited environment for storing secrets, and integrates seamlessly with App Service via App Service Key Vault References for enhanced security.", "waf": "Security" }, { - "category": "Identity and Access Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Managed Identity eliminates the need for hard-coded credentials by allowing App Service to authenticate to Azure Key Vault securely. This reduces the risk of credential exposure and simplifies secret management for enhanced security.", + "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "service": "App Services", "services": [ - "RBAC", + "AppSvc", + "AKV", "Entra" ], - "severity": "Medium", - "subcategory": "Identity", - "text": "Use Privileged Identity Management in AAD for ARO users with privileged roles.", + "severity": "High", + "subcategory": "Data Protection", + "text": "Use Managed Identity to securely connect to Azure Key Vault for accessing secrets, through App Service Key Vault References.", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "aa369282-9e7e-4216-8836-87af467a1f89", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Storing TLS certificates in Azure Key Vault enhances security by providing centralized, secure management and automated renewal of certificates. This reduces the risk of manual handling errors and certificate expiration.", + "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", + "service": "App Services", "services": [ - "VNet", - "Subscriptions", - "Firewall", - "WAF", - "DDoS", + "AppSvc", + "AKV", "Entra" ], - "severity": "Low", - "subcategory": "DDoS", - "text": "Use Azure DDoS Network/IP Protection to protect the virtual network you use for the ARO cluster unless you use Azure Firewall or WAF in a centralized subscription", + "severity": "High", + "subcategory": "Data Protection", + "text": "Use Azure Key Vault to securely store and manage TLS certificates for App Service.", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "35bda433-24f1-4481-8533-182aa5174269", - "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", - "services": [], - "severity": "High", - "subcategory": "Encryption", - "text": "All web applications you configure to use an ingress should use TLS encryption and shouldn't allow access over unencrypted HTTP.", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "To minimize exposure and improve security, isolate systems processing sensitive data. Leverage separate App Service Plans or App Service Environments for isolation, and use different subscriptions or management groups to enforce stricter boundaries and governance.", + "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", + "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", + "service": "App Services", + "services": [ + "AppSvc", + "Subscriptions" + ], + "severity": "Medium", + "subcategory": "Data Protection", + "text": "Isolate systems that process sensitive information using separate App Service Plans, App Service Environments (ASE), and consider different subscriptions or management groups for enhanced security.", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "44008ae7-d7e4-4743-876c-8bdbf55bce61", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Local disks on App Service are not encrypted and sensitive data should not be stored on those. (For example: D:\\\\Local and %TMP%).", + "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", + "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", + "service": "App Services", "services": [ - "FrontDoor", - "WAF" + "AppSvc", + "TrafficManager" ], "severity": "Medium", - "subcategory": "Internet", - "text": "Use Azure Front Door with WAF to securely publish ARO applications to the internet, especially in multi-region environments.", + "subcategory": "Data Protection", + "text": "Do not store sensitive data on local disk", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "9e8a03f9-7879-4424-b626-786d60b96c97", - "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Use Microsoft Entra ID or B2C for secure user authentication and Single Sign-On (SSO) across applications. Integrate using the built-in App Service Authentication/Authorization feature for streamlined security and compliance with modern authentication protocols like OpenID Connect.", + "guid": "919ca0b2-c121-459e-814b-933df574eccc", + "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", + "service": "App Services", "services": [ - "PrivateLink", - "FrontDoor" + "AppSvc", + "Entra", + "ACR" ], "severity": "Medium", - "subcategory": "Internet", - "text": "If exposing an app on ARO with Azure Front Door, use private link to connect Front Door with the ARO router.", + "subcategory": "Identity and Access Control", + "text": "Use Microsoft Entra ID or B2C for secure authentication and Single Sign-On (SSO).", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "be985190-4838-435c-a86b-b2912155a114", - "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Ensure all code deployments to App Service originate from a controlled, secured environment, such as a well-managed DevOps pipeline. This practice mitigates the risk of deploying unauthorized or malicious code by enforcing version control, code verification, and secure hosting.", + "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", + "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", + "service": "App Services", "services": [ - "NVA", - "Firewall", - "AzurePolicy" + "AppSvc", + "Entra" ], - "severity": "Medium", - "subcategory": "Internet", - "text": "If your security policy requires you to inspect all outbound internet traffic that's generated in the ARO cluster, secure egress network traffic by using Azure Firewall or an NVA.", + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Deploy code to App Service from a trusted and secure environment.", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "75e39f54-0acc-4cd9-9937-6bcda3750ab2", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Disable basic authentication for FTP/FTPS and WebDeploy/SCM to enhance security by enforcing Microsoft Entra ID secured endpoints for deployment. This ensures that only authenticated users using Microsoft Entra ID credentials can access deployment services, including the SCM site.", + "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", + "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", + "service": "App Services", "services": [ - "AzurePolicy" + "AppSvc", + "Entra" ], "severity": "High", - "subcategory": "Private access", - "text": "If your security policy requires you to use a private IP address for the OpenShift API, deploy a private ARO cluster.", + "subcategory": "Identity and Access Control", + "text": "Disable basic authentication for FTP/FTPS and WebDeploy/SCM.", "waf": "Security" }, { - "category": "Network topology and connectivity", - "checklist": "Azure Red Hat OpenShift", - "guid": "ab039da6-d54d-47c8-a29d-b107d5325ae6", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Wherever possible, use Managed Identity to securely connect to Microsoft Entra ID-secured resources without storing credentials. If this is not feasible, store secrets in Azure Key Vault and access them using Managed Identity to maintain security and reduce the risk of credential exposure.", + "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", + "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", + "service": "App Services", "services": [ - "ACR", - "PrivateLink" + "AppSvc", + "AKV", + "Entra" ], - "severity": "Medium", - "subcategory": "Private access", - "text": "Use Azure Private Link to secure network connections to managed Azure services, including to Azure Container Registry.", + "severity": "High", + "subcategory": "Identity and Access Control", + "text": "Use Managed Identity to connect to Microsoft Entra ID secured resources.", "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "25ca44e4-685e-4222-9ace-8bb12307ca5f", - "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "When using images stored in Azure Container Registry, pull these images using a Managed Identity to avoid storing credentials. This ensures secure access to container images and reduces the risk of credential exposure.", + "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", + "service": "App Services", "services": [ - "Monitor" + "AppSvc", + "Entra", + "ACR" ], "severity": "High", - "subcategory": "Operations", - "text": "Establish a monitoring process using the inbuilt Prometheus, OpenShift Logging or Container Insights integration.", - "waf": "Operations" + "subcategory": "Identity and Access Control", + "text": "Pull container images from Azure Container Registry using a Managed Identity.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "16f154e3-aa36-4928-89e7-e216183687af", - "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", - "services": [], - "severity": "Medium", - "subcategory": "Operations", - "text": "Automate the application delivery process through DevOps practices and CI/CD solutions, such as Pipelines/GitOps provided by OpenShift.", - "waf": "Operations" - }, - { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "467a1f89-35bd-4a43-924f-14811533182a", - "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", - "services": [], - "severity": "Low", - "subcategory": "Operations", - "text": "Whenever possible, remove the service state from inside containers. Instead, use an Azure platform as a service (PaaS) that supports multiregion replication.", - "waf": "Operations" - }, - { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "1b7da8cf-aa66-4e15-b4d5-ada97dc3e232", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Configure diagnostic settings to send telemetry and security logs (including HTTP, platform, and audit logs) to Log Analytics. Centralized logging enhances monitoring, threat detection, and compliance reporting.", + "guid": "47768314-c115-4775-a2ea-55b46ad48408", + "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", + "service": "App Services", "services": [ - "Storage" + "AppSvc", + "Entra", + "Monitor" ], - "severity": "Low", - "subcategory": "Operations", - "text": "Use RWX storage with inbuilt Azure Files storage class.", - "waf": "Operations" - }, - { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "6bb235c7-05e1-4696-bded-fa8a4c8cdec4", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", - "services": [], "severity": "Medium", - "subcategory": "Performance", - "text": "Use pod requests and limits to manage the compute resources within a cluster.", - "waf": "Performance" + "subcategory": "Logging and Monitoring", + "text": "Send App Service runtime and security logs to Log Analytics for centralized monitoring and alerting.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "c620c30c-14ee-4b7f-9ae8-d9b3fec228e7", - "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", - "services": [], + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Set up a diagnostic setting to send the activity log to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the App Service resource itself.", + "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "service": "App Services", + "services": [ + "AppSvc", + "Monitor", + "Entra" + ], "severity": "Medium", - "subcategory": "Performance", - "text": "Enforce resource quotas on projects.", - "waf": "Performance" + "subcategory": "Logging and Monitoring", + "text": "Send App Service activity logs to Log Analytics", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "87ab177a-db59-4f6b-a613-334fd09dc234", - "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", - "services": [], - "severity": "High", - "subcategory": "Performance", - "text": "Define ClusterAutoScaler and MachineAutoScaler to scale machines when your cluster runs out of resources to support more deployments.", - "waf": "Performance" + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Use regional VNet integration, Network Security Groups (NSGs), and User-Defined Routes (UDRs) to control outbound network access. Route traffic through a Network Virtual Appliance (NVA), such as Azure Firewall, and monitor firewall logs to ensure traffic is properly controlled and secure.", + "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", + "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", + "service": "App Services", + "services": [ + "AppSvc", + "NVA", + "Monitor", + "VNet", + "Firewall" + ], + "severity": "Medium", + "subcategory": "Network Security", + "text": "Control outbound network access for App Service using VNet integration, NSGs, UDRs, and firewalls.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "19db6128-1269-4040-a4ba-4d3e0804276d", - "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Provide a stable outbound IP by using VNet integration with a NAT Gateway or Network Virtual Appliance (NVA) like Azure Firewall. This enables the receiving party to allow-list based on IP, if necessary. For communications with Azure services, use mechanisms like Service Endpoints or private endpoints to avoid relying on static IPs, ensuring secure and efficient connectivity.", + "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", + "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", + "service": "App Services", "services": [ - "VM" + "AppSvc", + "PrivateLink", + "NVA", + "Storage", + "VNet", + "Firewall" ], - "severity": "High", - "subcategory": "Reliability", - "text": "Use virtual machine sizes that are large enough to contain multiple container instances so you get the benefits of increased density, but not so large that your cluster can't handle the workload of a failing node.", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Network Security", + "text": "Ensure a stable IP for outbound communications by using VNet NAT Gateway or Azure Firewall.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "4b98b15c-8b31-4aa5-aceb-58889135e227", - "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", - "services": [], + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Control inbound network access by configuring App Service Access Restrictions, Service Endpoints, or Private Endpoints. Ensure appropriate restrictions are set for both the web app and the SCM (deployment) site to limit unauthorized access and enhance security.", + "guid": "0725769e-e669-41a4-a34a-c932223ece80", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "service": "App Services", + "services": [ + "AppSvc", + "PrivateLink" + ], "severity": "High", - "subcategory": "Reliability", - "text": "Deploy machine health checks to automatically repair damaged machines in a machine pool.", - "waf": "Reliability" + "subcategory": "Network Security", + "text": "Control inbound network access using Access Restrictions, Service Endpoints, or Private Endpoints.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "896d31b6-6c67-4ba5-a119-c08e8f5d587c", - "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Protect App Service from malicious inbound traffic by deploying a Web Application Firewall (WAF) using Azure Application Gateway or Azure Front Door. Ensure WAF logs are monitored regularly to detect and respond to security threats.", + "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", + "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", + "service": "App Services", "services": [ + "AppSvc", + "AppGW", + "WAF", + "FrontDoor", "Monitor" ], "severity": "High", - "subcategory": "Reliability", - "text": "Use an alerting system to provide notifications when things need direct action: Container Insights metric alerts or in-built Alerting UI.", - "waf": "Reliability" + "subcategory": "Network Security", + "text": "Use a Web Application Firewall (WAF) in front of App Service.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "7e9ced16-acd1-476e-b9b2-41a998a57ae7", - "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview#availability-zones", - "services": [], + "category": "Security", + "checklist": "Azure App Service Review", + "description": "To prevent the Web Application Firewall (WAF) from being bypassed, lock down access to App Service by using Access Restrictions, Service Endpoints, and Private Endpoints. This ensures that all traffic is routed through the WAF, providing a secure front layer of protection.", + "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "service": "App Services", + "services": [ + "AppSvc", + "WAF", + "PrivateLink" + ], "severity": "High", - "subcategory": "Reliability", - "text": "Ensure that the cluster is created in a region that supports AZs and create a machine set for each AZ.", - "waf": "Reliability" + "subcategory": "Network Security", + "text": "Ensure the WAF cannot be bypassed by securing access to App Service.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "7b997e71-1b7d-4a8c-baa6-6e15d4d5ada9", - "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Ensure that the minimum TLS policy is set to 1.2 or higher, with a preference for TLS 1.3, to enhance security through stronger encryption protocols. TLS 1.3 provides additional security improvements and faster handshake times, reducing vulnerabilities associated with older versions.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", + "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", + "service": "App Services", "services": [ - "AKS" + "AppSvc", + "AzurePolicy" ], - "severity": "Low", - "subcategory": "Reliability", - "text": "Create infrastructure machine sets to hold infrastructure components. Apply specific Kubernetes labels to these machines and then update the infrastructure components to run on only those machines.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Network Security", + "text": "Set minimum TLS policy to 1.2 or higher, preferably 1.3, in App Service configuration.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "7dc3e232-6bb2-435c-905e-1696fdedfa8a", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup#create-a-backup-with-velero-to-include-snapshots", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Configure App Service to enforce HTTPS-only, automatically redirecting all HTTP traffic to HTTPS. Additionally, implement HTTP Strict Transport Security (HSTS) in your code or via a Web Application Firewall (WAF) to ensure browsers only access the site over HTTPS, enhancing security by preventing downgrade attacks.", + "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", + "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", + "service": "App Services", "services": [ - "Backup" + "AppSvc", + "WAF" ], - "severity": "Medium", - "subcategory": "Reliability", - "text": "Create application backup and plan for restore and include persistent volumes in the backup.", - "waf": "Reliability" + "severity": "High", + "subcategory": "Network Security", + "text": "Use HTTPS only and consider enabling HTTP Strict Transport Security (HSTS).", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "81c12318-1a64-4174-8583-3fb4ae3c2df7", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-priority.html", - "services": [], - "severity": "Low", - "subcategory": "Reliability", - "text": "Use pod priorities, so that in case of limited resources the most critical pods will run.", - "waf": "Reliability" + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Do not use wildcards (*) in your CORS configuration, as this permits unrestricted access from any origin, compromising security. Instead, explicitly specify trusted origins that are allowed to access the service, ensuring controlled access.", + "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", + "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", + "service": "App Services", + "services": [ + "AppSvc", + "Storage" + ], + "severity": "High", + "subcategory": "Network Security", + "text": "Avoid using wildcards for CORS; specify allowed origins explicitly.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "43166c3b-cbe0-45bb-b209-d4a0da577784", - "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Remote debugging should not be enabled in production as it opens additional ports, increasing the attack surface. Although App Service automatically turns off remote debugging after 48 hours, it is recommended to disable it manually in production to maintain a secure environment.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", + "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", + "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", + "service": "App Services", "services": [ - "AzurePolicy" + "AppSvc" ], - "severity": "Low", - "subcategory": "Security", - "text": "Regulate cluster functions using admission plug-ins, which are commonly used to enforce security policy, resource limitations, or configuration requirements.", + "severity": "High", + "subcategory": "Network Security", + "text": "Turn off remote debugging in production environments.", "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "24d21678-5d2f-4a56-a56a-d48408fe8273", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Enable Defender for App Service. This (amongst other threats) detects communications to known malicious IP addresses. Review the recommendations from Defender for App Service as part of your operations.", + "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", + "service": "App Services", "services": [ - "ACR" + "AppSvc", + "Defender" ], - "severity": "Low", - "subcategory": "Security", - "text": "Store your container images in Azure Container Registry and geo-replicate the registry to each region.", + "severity": "Medium", + "subcategory": "Network Security", + "text": "Enable Defender for Cloud - Defender for App Service", "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "4c486ba2-80dc-4059-8cf7-5ee8e1309ccc", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", - "services": [], + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Azure provides DDoS Basic protection on its network, which can be improved with intelligent DDoS Standard capabilities which learns about normal traffic patterns and can detect unusual behavior. DDoS Standard applies to a Virtual Network so it must be configured for the network resource in front of the app, such as Application Gateway or an NVA.", + "guid": "223ece80-b123-4071-a541-6415833ea3ad", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "service": "App Services", + "services": [ + "AppSvc", + "AppGW", + "DDoS", + "WAF", + "NVA", + "EventHubs", + "VNet" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Optimize the CPU and memory request values, and maximize the efficiency of the cluster resources using vertical pod autoscaler.", - "waf": "Performance" + "subcategory": "Network Security", + "text": "Enable DDOS Protection Standard on the WAF VNet", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "d579366b-cda2-4750-aa1a-bfe9d55d14c3", - "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "When using images stored in Azure Container Registry, ensure they are pulled over a virtual network by using a private endpoint and configuring the app setting 'WEBSITE_PULL_IMAGE_OVER_VNET'. This ensures secure communication between App Service and the registry, preventing exposure to the public internet.", + "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", + "service": "App Services", "services": [ - "Monitor" + "AppSvc", + "VNet", + "PrivateLink", + "ACR" ], "severity": "Medium", - "subcategory": "Workload", - "text": "Add health probes to your pods to monitor application health. Make sure pods contain livenessProbe and readinessProbe. Use Startup probes to determine the point at which the application has started up.", - "waf": "Reliability" + "subcategory": "Network Security", + "text": "Pull container images over a Virtual Network from Azure Container Registry.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "c4929cb1-b3d1-4325-ae12-4ba34d0685ed", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", - "services": [], + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Perform a penetration test on the web application in accordance with Azure's penetration testing rules of engagement. This helps identify vulnerabilities and security weaknesses that can be addressed before they are exploited.", + "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", + "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", + "service": "App Services", + "services": [ + "AppSvc" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Scale pods to meet demand using horizontal pod autoscaler.", - "waf": "Reliability" + "subcategory": "Penetration Testing", + "text": "Conduct a penetration test on the web application.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "dce9be3b-b0dd-4b3b-95fb-2ec14eeaa359", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Ensure that only trusted code, which has been validated and scanned for vulnerabilities, is deployed to production following DevSecOps practices. This minimizes the risk of introducing security vulnerabilities into the application environment.", + "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", + "service": "App Services", "services": [ - "Cost" + "AppSvc" ], "severity": "Medium", - "subcategory": "Workload", - "text": "Use disruption budgets to ensure the required number of pod replicas exist to handle expected application load.", - "waf": "Reliability" + "subcategory": "Vulnerability Management", + "text": "Deploy validated and vulnerability-scanned code.", + "waf": "Security" }, { - "category": "Operations management", - "checklist": "Azure Red Hat OpenShift", - "guid": "2829e2ed-b217-4367-9aff-6791b4935ada", - "link": "https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-pod-topology-spread-constraints.html", - "services": [], + "category": "Security", + "checklist": "Azure App Service Review", + "description": "Ensure that the latest versions of supported platforms, programming languages, protocols, and frameworks are used. Regular updates mitigate the risk of security vulnerabilities and ensure compatibility with security patches.", + "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", + "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", + "service": "App Services", + "services": [ + "AppSvc" + ], + "severity": "High", + "subcategory": "Vulnerability Management", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "waf": "Security" + }, + { + "category": "Operations", + "checklist": "Azure App Service Review", + "description": "Leverage Auto-Healing in Azure App Service to automatically restart instances or trigger custom actions based on pre-defined failure conditions like memory thresholds, HTTP errors, or specific event logs.", + "guid": "60b3a935-33e5-45c9-87c7-53882e395b46", + "link": "https://learn.microsoft.com/azure/app-service/overview-diagnostics", + "service": "App Services", + "services": [ + "AppSvc" + ], "severity": "Medium", - "subcategory": "Workload", - "text": "Use pod topology constraints to automatically schedule pods on nodes throughout the cluster.", + "subcategory": "High Availability", + "text": "Use Auto-Healing with custom rules to restart App Service instances automatically when failures occur.", "waf": "Reliability" }, { - "category": "Operations Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "fea1dbf3-dd95-4d48-a7c8-91dcb1f7d575", - "link": "https://learn.microsoft.com/azure/openshift/intro-openshift#service-level-agreement", - "services": [], + "category": "Operations", + "checklist": "Azure App Service Review", + "description": "Configure Azure Monitor alerts based on Application Insights metrics for response times, failure rates, and overall availability. Alerts help detect issues proactively and reduce mean-time-to-recovery (MTTR).", + "guid": "e52e4514-02a7-4e81-a98e-88ce1b18e557", + "link": "https://learn.microsoft.com/azure/azure-monitor/app/alerts", + "service": "App Services", + "services": [ + "AppSvc", + "Monitor" + ], "severity": "Medium", - "subcategory": "Availablity", - "text": "Leverage Current ARO SLA - 99.95 into BCDR planning", + "subcategory": "Monitoring", + "text": "Set up alerts for critical Application Insights metrics, such as response time and failure rates.", "waf": "Reliability" }, { - "category": "Operations Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "b95e06e1-58e2-4ea3-a92c-2de6e2065b3a", - "link": "https://www.redhat.com/rhdc/managed-files/pa-getting-started-azure-openshift-ebook-f20686-201911-en_0.pdf", - "services": [], + "category": "Governance and Security", + "checklist": "Azure App Service Review", + "description": "Use Azure Policy to enforce security, compliance, and governance configurations for App Service. Policies can ensure that critical settings such as TLS versions, backup configurations, and network restrictions are enforced across all App Service instances.", + "guid": "361e886f-ca40-4ead-a8e9-1379c642ae9c", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "App Services", + "services": [ + "AppSvc", + "Backup", + "AzurePolicy", + "ACR" + ], "severity": "High", - "subcategory": "Cluster Design", - "text": "Run user workloads on the worker nodes, not the control plane nodes", - "waf": "Reliability" + "subcategory": "Compliance", + "text": "Apply Azure Policy to enforce compliance across App Service configurations.", + "waf": "Governance" }, { - "category": "Operations Management", - "checklist": "Azure Red Hat OpenShift", - "description": "Create infrastructure machine sets to hold infrastructure components. Apply specific Kubernetes labels to these machines and then update the infrastructure components to run on only those machines", - "guid": "76af4a69-1e88-439a-ba46-667e13c10567", - "link": "https://learn.microsoft.com/azure/openshift/howto-segregate-machinesets", + "category": "Cost Governance", + "checklist": "Azure App Service Review", + "description": "Leverage Azure Cost Management to track and forecast App Service expenses. Set up alerts for budget thresholds to avoid overspending, and optimize costs based on resource utilization trends.", + "guid": "42eb48f0-28ff-497c-b2c0-a8fa1f989832", + "link": "https://learn.microsoft.com/azure/cost-management-billing/", + "service": "App Services", "services": [ - "AKS", - "VNet" + "AppSvc", + "Monitor", + "Cost" ], - "severity": "Medium", - "subcategory": "Cluster Design", - "text": "Isolate workloads into worker nodes running in individual subnets as needed", - "waf": "Reliability" + "severity": "Low", + "subcategory": "Cost Monitoring", + "text": "Monitor App Service costs using Azure Cost Management and create cost alerts.", + "waf": "Cost" }, { - "category": "Operations Management", - "checklist": "Azure Red Hat OpenShift", - "guid": "785c6fe9-6c96-4ad8-a44c-f3b2b38c886b", - "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup", + "category": "Cost Governance", + "checklist": "Azure App Service Review", + "description": "If you have predictable and steady usage of App Service, purchasing Reserved Instances can significantly reduce long-term costs. Commit to one or three years for lower pricing compared to pay-as-you-go.", + "guid": "e489221b-487e-48a3-aaab-48e3d205ca12", + "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/", + "service": "App Services", "services": [ - "Backup" + "AppSvc", + "ARS", + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Backup a cluster state for stateful workload scenarios to a paired region", - "waf": "Reliability" + "subcategory": "Cost Optimization", + "text": "Purchase reserved instances for App Service plans to optimize long-term costs.", + "waf": "Cost" }, { - "category": "Operations Management", + "category": "Identity and Access Management", "checklist": "Azure Red Hat OpenShift", - "guid": "a2c02149-9014-4a5d-9ce5-74dccbd9792a", - "link": "https://access.redhat.com/documentation/red_hat_openshift_container_storage/4.4/html/deploying_and_managing_openshift_container_storage_on_microsoft_azure/deploying-openshift-container-storage-on-microsoft-azure_rhocs", + "guid": "d7e47431-76c8-4bdb-b55b-ce619e8a03f9", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-service-principal?pivots=aro-azurecli", "services": [ - "ACR", - "Storage" + "RBAC", + "Entra" ], - "severity": "Medium", - "subcategory": "Data Store", - "text": "If container storage is required, ensure availability across regions if needed: Using RWX storage with inbuilt Azure Files storage class. Using CSI Drivers for storage provisioning", - "waf": "Reliability" + "severity": "High", + "subcategory": "Identity", + "text": "Create a service principal and its role assignments before creating the ARO clusters.", + "waf": "Security" }, { - "category": "Operations Management", + "category": "Identity and Access Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "7879424d-6267-486d-90b9-6c97be985190", + "link": "https://learn.microsoft.com/azure/openshift/configure-azure-ad-ui", + "services": [ + "Entra" + ], + "severity": "High", + "subcategory": "Identity", + "text": "Use AAD to authenticate users in your ARO cluster.", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "adfec5f9-a82d-46e9-a8d1-5a0c7fed5d15", + "link": "https://docs.openshift.com/container-platform/4.14/authentication/remove-kubeadmin.html", + "services": [ + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "When using AAD authentication, remove kubeadmin user from the cluster.", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "483835c9-86bb-4291-8155-a11475e39f54", + "link": "https://docs.openshift.com/container-platform/4.13/applications/projects/working-with-projects.html", + "services": [ + "RBAC", + "Entra" + ], + "severity": "High", + "subcategory": "Identity", + "text": "Define OpenShift projects to restrict RBAC privilege and isolate workloads in your cluster.", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "0acccd97-9376-4bcd-a375-0ab2ab039da6", + "link": "https://docs.openshift.com/container-platform/4.13/authentication/using-rbac.html", + "services": [ + "RBAC", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "Define the required RBAC roles in OpenShift are scoped to either a project or a cluster.", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "d54d7c89-29db-4107-b532-5ae625ca44e4", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "services": [ + "AKV", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "Minimize the number of users who have administrator rights and secrets access.", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "685e2223-ace8-4bb1-8307-ca5f16f154e3", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "services": [ + "RBAC", + "Entra" + ], + "severity": "Medium", + "subcategory": "Identity", + "text": "Use Privileged Identity Management in AAD for ARO users with privileged roles.", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "aa369282-9e7e-4216-8836-87af467a1f89", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "services": [ + "WAF", + "DDoS", + "Entra", + "VNet", + "Firewall", + "Subscriptions" + ], + "severity": "Low", + "subcategory": "DDoS", + "text": "Use Azure DDoS Network/IP Protection to protect the virtual network you use for the ARO cluster unless you use Azure Firewall or WAF in a centralized subscription", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "35bda433-24f1-4481-8533-182aa5174269", + "link": "https://docs.openshift.com/container-platform/4.13/networking/routes/secured-routes.html", + "services": [], + "severity": "High", + "subcategory": "Encryption", + "text": "All web applications you configure to use an ingress should use TLS encryption and shouldn't allow access over unencrypted HTTP.", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "44008ae7-d7e4-4743-876c-8bdbf55bce61", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", + "services": [ + "FrontDoor", + "WAF" + ], + "severity": "Medium", + "subcategory": "Internet", + "text": "Use Azure Front Door with WAF to securely publish ARO applications to the internet, especially in multi-region environments.", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "9e8a03f9-7879-4424-b626-786d60b96c97", + "link": "https://learn.microsoft.com/azure/openshift/howto-secure-openshift-with-front-door", + "services": [ + "PrivateLink", + "FrontDoor" + ], + "severity": "Medium", + "subcategory": "Internet", + "text": "If exposing an app on ARO with Azure Front Door, use private link to connect Front Door with the ARO router.", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "be985190-4838-435c-a86b-b2912155a114", + "link": "https://learn.microsoft.com/azure/openshift/howto-restrict-egress", + "services": [ + "Firewall", + "AzurePolicy", + "NVA" + ], + "severity": "Medium", + "subcategory": "Internet", + "text": "If your security policy requires you to inspect all outbound internet traffic that's generated in the ARO cluster, secure egress network traffic by using Azure Firewall or an NVA.", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "75e39f54-0acc-4cd9-9937-6bcda3750ab2", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-private-cluster-4x", + "services": [ + "AzurePolicy" + ], + "severity": "High", + "subcategory": "Private access", + "text": "If your security policy requires you to use a private IP address for the OpenShift API, deploy a private ARO cluster.", + "waf": "Security" + }, + { + "category": "Network topology and connectivity", + "checklist": "Azure Red Hat OpenShift", + "guid": "ab039da6-d54d-47c8-a29d-b107d5325ae6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "services": [ + "PrivateLink", + "ACR" + ], + "severity": "Medium", + "subcategory": "Private access", + "text": "Use Azure Private Link to secure network connections to managed Azure services, including to Azure Container Registry.", + "waf": "Security" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "25ca44e4-685e-4222-9ace-8bb12307ca5f", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-enable-arc-enabled-clusters", + "services": [ + "Monitor" + ], + "severity": "High", + "subcategory": "Operations", + "text": "Establish a monitoring process using the inbuilt Prometheus, OpenShift Logging or Container Insights integration.", + "waf": "Operations" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "16f154e3-aa36-4928-89e7-e216183687af", + "link": "https://docs.openshift.com/container-platform/4.13/cicd/pipelines/understanding-openshift-pipelines.html", + "services": [], + "severity": "Medium", + "subcategory": "Operations", + "text": "Automate the application delivery process through DevOps practices and CI/CD solutions, such as Pipelines/GitOps provided by OpenShift.", + "waf": "Operations" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "467a1f89-35bd-4a43-924f-14811533182a", + "link": "https://learn.microsoft.com/azure/architecture/guide/design-principles/managed-services", + "services": [], + "severity": "Low", + "subcategory": "Operations", + "text": "Whenever possible, remove the service state from inside containers. Instead, use an Azure platform as a service (PaaS) that supports multiregion replication.", + "waf": "Operations" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "1b7da8cf-aa66-4e15-b4d5-ada97dc3e232", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-storageclass", + "services": [ + "Storage" + ], + "severity": "Low", + "subcategory": "Operations", + "text": "Use RWX storage with inbuilt Azure Files storage class.", + "waf": "Operations" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "6bb235c7-05e1-4696-bded-fa8a4c8cdec4", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/clusters/nodes-cluster-limit-ranges.html", + "services": [], + "severity": "Medium", + "subcategory": "Performance", + "text": "Use pod requests and limits to manage the compute resources within a cluster.", + "waf": "Performance" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "c620c30c-14ee-4b7f-9ae8-d9b3fec228e7", + "link": "https://docs.openshift.com/container-platform/4.13/applications/quotas/quotas-setting-per-project.html", + "services": [], + "severity": "Medium", + "subcategory": "Performance", + "text": "Enforce resource quotas on projects.", + "waf": "Performance" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "87ab177a-db59-4f6b-a613-334fd09dc234", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/applying-autoscaling.html", + "services": [], + "severity": "High", + "subcategory": "Performance", + "text": "Define ClusterAutoScaler and MachineAutoScaler to scale machines when your cluster runs out of resources to support more deployments.", + "waf": "Performance" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "19db6128-1269-4040-a4ba-4d3e0804276d", + "link": "https://learn.microsoft.com/azure/openshift/support-policies-v4#supported-virtual-machine-sizes", + "services": [ + "VM" + ], + "severity": "High", + "subcategory": "Reliability", + "text": "Use virtual machine sizes that are large enough to contain multiple container instances so you get the benefits of increased density, but not so large that your cluster can't handle the workload of a failing node.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "4b98b15c-8b31-4aa5-aceb-58889135e227", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/deploying-machine-health-checks.html", + "services": [], + "severity": "High", + "subcategory": "Reliability", + "text": "Deploy machine health checks to automatically repair damaged machines in a machine pool.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "896d31b6-6c67-4ba5-a119-c08e8f5d587c", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-metric-alerts", + "services": [ + "Monitor" + ], + "severity": "High", + "subcategory": "Reliability", + "text": "Use an alerting system to provide notifications when things need direct action: Container Insights metric alerts or in-built Alerting UI.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "7e9ced16-acd1-476e-b9b2-41a998a57ae7", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview#availability-zones", + "services": [], + "severity": "High", + "subcategory": "Reliability", + "text": "Ensure that the cluster is created in a region that supports AZs and create a machine set for each AZ.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "7b997e71-1b7d-4a8c-baa6-6e15d4d5ada9", + "link": "https://docs.openshift.com/container-platform/4.13/machine_management/creating-infrastructure-machinesets.html", + "services": [ + "AKS" + ], + "severity": "Low", + "subcategory": "Reliability", + "text": "Create infrastructure machine sets to hold infrastructure components. Apply specific Kubernetes labels to these machines and then update the infrastructure components to run on only those machines.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "7dc3e232-6bb2-435c-905e-1696fdedfa8a", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup#create-a-backup-with-velero-to-include-snapshots", + "services": [ + "Backup" + ], + "severity": "Medium", + "subcategory": "Reliability", + "text": "Create application backup and plan for restore and include persistent volumes in the backup.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "81c12318-1a64-4174-8583-3fb4ae3c2df7", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-priority.html", + "services": [], + "severity": "Low", + "subcategory": "Reliability", + "text": "Use pod priorities, so that in case of limited resources the most critical pods will run.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "43166c3b-cbe0-45bb-b209-d4a0da577784", + "link": "https://docs.openshift.com/container-platform/4.13/architecture/admission-plug-ins.html", + "services": [ + "AzurePolicy" + ], + "severity": "Low", + "subcategory": "Security", + "text": "Regulate cluster functions using admission plug-ins, which are commonly used to enforce security policy, resource limitations, or configuration requirements.", + "waf": "Security" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "24d21678-5d2f-4a56-a56a-d48408fe8273", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", + "services": [ + "ACR" + ], + "severity": "Low", + "subcategory": "Security", + "text": "Store your container images in Azure Container Registry and geo-replicate the registry to each region.", + "waf": "Security" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "4c486ba2-80dc-4059-8cf7-5ee8e1309ccc", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-vertical-autoscaler.html", + "services": [], + "severity": "Medium", + "subcategory": "Workload", + "text": "Optimize the CPU and memory request values, and maximize the efficiency of the cluster resources using vertical pod autoscaler.", + "waf": "Performance" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "d579366b-cda2-4750-aa1a-bfe9d55d14c3", + "link": "https://docs.openshift.com/container-platform/4.13/applications/application-health.html", + "services": [ + "Monitor" + ], + "severity": "Medium", + "subcategory": "Workload", + "text": "Add health probes to your pods to monitor application health. Make sure pods contain livenessProbe and readinessProbe. Use Startup probes to determine the point at which the application has started up.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "c4929cb1-b3d1-4325-ae12-4ba34d0685ed", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-autoscaling.html", + "services": [], + "severity": "Medium", + "subcategory": "Workload", + "text": "Scale pods to meet demand using horizontal pod autoscaler.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "dce9be3b-b0dd-4b3b-95fb-2ec14eeaa359", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/pods/nodes-pods-configuring.html#nodes-pods-pod-distruption-about_nodes-pods-configuring", + "services": [ + "Cost" + ], + "severity": "Medium", + "subcategory": "Workload", + "text": "Use disruption budgets to ensure the required number of pod replicas exist to handle expected application load.", + "waf": "Reliability" + }, + { + "category": "Operations management", + "checklist": "Azure Red Hat OpenShift", + "guid": "2829e2ed-b217-4367-9aff-6791b4935ada", + "link": "https://docs.openshift.com/container-platform/4.13/nodes/scheduling/nodes-scheduler-pod-topology-spread-constraints.html", + "services": [], + "severity": "Medium", + "subcategory": "Workload", + "text": "Use pod topology constraints to automatically schedule pods on nodes throughout the cluster.", + "waf": "Reliability" + }, + { + "category": "Operations Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "fea1dbf3-dd95-4d48-a7c8-91dcb1f7d575", + "link": "https://learn.microsoft.com/azure/openshift/intro-openshift#service-level-agreement", + "services": [], + "severity": "Medium", + "subcategory": "Availablity", + "text": "Leverage Current ARO SLA - 99.95 into BCDR planning", + "waf": "Reliability" + }, + { + "category": "Operations Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "b95e06e1-58e2-4ea3-a92c-2de6e2065b3a", + "link": "https://www.redhat.com/rhdc/managed-files/pa-getting-started-azure-openshift-ebook-f20686-201911-en_0.pdf", + "services": [], + "severity": "High", + "subcategory": "Cluster Design", + "text": "Run user workloads on the worker nodes, not the control plane nodes", + "waf": "Reliability" + }, + { + "category": "Operations Management", + "checklist": "Azure Red Hat OpenShift", + "description": "Create infrastructure machine sets to hold infrastructure components. Apply specific Kubernetes labels to these machines and then update the infrastructure components to run on only those machines", + "guid": "76af4a69-1e88-439a-ba46-667e13c10567", + "link": "https://learn.microsoft.com/azure/openshift/howto-segregate-machinesets", + "services": [ + "VNet", + "AKS" + ], + "severity": "Medium", + "subcategory": "Cluster Design", + "text": "Isolate workloads into worker nodes running in individual subnets as needed", + "waf": "Reliability" + }, + { + "category": "Operations Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "785c6fe9-6c96-4ad8-a44c-f3b2b38c886b", + "link": "https://learn.microsoft.com/azure/openshift/howto-create-a-backup", + "services": [ + "Backup" + ], + "severity": "Medium", + "subcategory": "Backup", + "text": "Backup a cluster state for stateful workload scenarios to a paired region", + "waf": "Reliability" + }, + { + "category": "Operations Management", + "checklist": "Azure Red Hat OpenShift", + "guid": "a2c02149-9014-4a5d-9ce5-74dccbd9792a", + "link": "https://access.redhat.com/documentation/red_hat_openshift_container_storage/4.4/html/deploying_and_managing_openshift_container_storage_on_microsoft_azure/deploying-openshift-container-storage-on-microsoft-azure_rhocs", + "services": [ + "Storage", + "ACR" + ], + "severity": "Medium", + "subcategory": "Data Store", + "text": "If container storage is required, ensure availability across regions if needed: Using RWX storage with inbuilt Azure Files storage class. Using CSI Drivers for storage provisioning", + "waf": "Reliability" + }, + { + "category": "Operations Management", "checklist": "Azure Red Hat OpenShift", "guid": "6bcca2b4-fea1-4dbf-9dd9-5d48c7c891dc", "link": "https://docs.openshift.com/aro/3/dev_guide/persistent_volumes.html", @@ -7389,8 +8445,8 @@ "guid": "d55d14c3-c492-49cb-8b3d-1325ae124ba3", "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "services": [ - "Defender", "Arc", + "Defender", "AKS" ], "severity": "Medium", @@ -7404,8 +8460,8 @@ "guid": "4d0685ed-dce9-4be3-ab0d-db3b55fb2ec1", "link": "https://learn.microsoft.com/azure/azure-arc/kubernetes/tutorial-akv-secrets-provider", "services": [ - "Arc", "AKV", + "Arc", "AKS" ], "severity": "Medium", @@ -7457,8 +8513,8 @@ "guid": "e209d4a0-da57-4778-924d-216785d2fa56", "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "services": [ - "ACR", - "Subscriptions" + "Subscriptions", + "ACR" ], "severity": "Low", "subcategory": "Workload", @@ -7484,8 +8540,8 @@ "guid": "f7c015e0-7d97-4283-b006-567afeb2b5ca", "link": "https://learn.microsoft.com/azure-stack/hci/concepts/drive-symmetry-considerations#understand-capacity-imbalance", "services": [ - "ACR", - "Storage" + "Storage", + "ACR" ], "severity": "Medium", "subcategory": "Physical", @@ -8316,8 +9372,8 @@ "service": "Cognitive Search", "services": [ "Storage", - "Backup", - "ASR" + "ASR", + "Backup" ], "severity": "High", "subcategory": "Disaster Recovery", @@ -8328,2699 +9384,1885 @@ "category": "Operations management", "checklist": "Azure Bot Service", "guid": "6ad48408-ee72-4734-a476-ba28fdcf590c", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-bot", - "service": "Bot service", - "services": [], - "severity": "Medium", - "subcategory": "High Availablity", - "text": "Follow reliability support recommendations in Azure Bot Service", - "waf": "Reliability" - }, - { - "category": "Operations management", - "checklist": "Azure Bot Service", - "guid": "e65de8e1-3f9c-4cbd-9682-66abca264f9a", - "link": "https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-concept-regionalization", - "service": "Bot service", - "services": [], - "severity": "Medium", - "subcategory": "High Availablity", - "text": "Deploying bots with local data residency and regional compliance", - "waf": "Reliability" - }, - { - "category": "Operations management", - "checklist": "Azure Bot Service", - "guid": "19bfe9d5-5d04-4c3c-9919-ca1b2d1215ae", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-bot#cross-region-disaster-recovery-in-multi-region-geography", - "service": "Bot service", - "services": [], - "severity": "Medium", - "subcategory": "High Availablity", - "text": "Azure Bot Service runs in active-active mode for both global and regional services. When an outage occurs, you don't need to detect errors or manage the service. Azure Bot Service automatically performs auto failover and auto recovery in a multi-region geographical architecture. For the EU bot regional service, Azure Bot Service provides two full regions inside Europe with active/active replication to ensure redundancy. For the global bot service, all available regions/geographies can be served as the global footprint.", - "waf": "Reliability" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "a95b86ad-8840-48e3-9273-4b875ba18f20", - "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", - "service": "Azure Monitor", - "services": [ - "Cost", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Azure Monitor - enforce data collection rules", - "text": "Data collection rules in Azure Monitor -https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-rule-overview", - "training": "https://azure.microsoft.com/pricing/reservations/", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "45901365-d38e-443f-abcb-d868266abca2", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", - "service": "Azure Backup", - "services": [ - "Cost", - "Backup" - ], - "severity": "Medium", - "subcategory": "Backup", - "text": "check backup instances with the underlying datasource not found", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "64f9a19a-f29c-495d-94c6-c7919ca0f6c5", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", - "service": "VM", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Delete/archive", - "text": "Delete or archive unassociated services (disks, nics, ip addresses etc)", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "659d3958-fd77-4289-a835-556df2bfe456", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Delete/archive", - "text": "Consider snooze and stop technique (snooze a service after x days, stop after 2x, delete/deallocate after 3x)", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "3b0d834a-3487-426d-b69c-6b5c2a26494b", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "services": [ - "Cost", - "Storage", - "Backup" - ], - "severity": "Medium", - "subcategory": "Delete/archive", - "text": "Delete or archive unused resources (old backups, logs, storage accounts, etc...)", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "69bad37a-ad53-4cc7-ae1d-76667357c449", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "service": "Azure Backup", - "services": [ - "Cost", - "Storage", - "Backup", - "ASR" - ], - "severity": "Medium", - "subcategory": "Delete/archive", - "text": "Consider a good balance between site recovery storage and backup for non mission critical applications", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "674b5ed8-5a85-49c7-933b-e2a1a27b765a", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", - "service": "Azure Monitor", - "services": [ - "Cost", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Log Analytics retention for workspaces", - "text": "Check spending and savings opportunities among the 40 different log analytics workspaces- use different retention and data collection for nonprod workspaces-create daily cap for awareness and tier sizing - If you do set a daily cap, in addition to creating an alert when the cap is reached,ensure that you also create an alert rule to be notified when some percentage has been reached (90% for example). - consider workspace transformation if possible - https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-transformations#workspace-transformation-dcr ", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/understand-work-scopes", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "91be1f38-8ef3-494c-8bd4-63cbbac75819", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", - "service": "Azure Monitor", - "services": [ - "Cost", - "Storage", - "AzurePolicy" - ], - "severity": "Medium", - "subcategory": "Policy", - "text": "Enforce a purging log policy and automation (if needed, logs can be moved to cold storage)", - "training": "https://www.youtube.com/watch?v=nHQYcYGKuyw", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "59bb91a3-ed90-4cae-8cc8-4c37b6b780cb", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Run orphaned resources workbook - delete or snooze ghost items", - "text": "https://github.com/dolevshor/azure-orphan-resources", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "9fe5c464-89d4-457a-a27c-3874d0102cac", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Shutdown/deallocate", - "text": "Shutdown underutilized instances", - "training": "https://learn.microsoft.com/azure/cost-management-billing/understand/analyze-unexpected-charges", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "6aae01e6-a84d-4e5d-b36d-1d92881a1bd5", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", - "service": "VM", - "services": [ - "Cost", - "Storage", - "Backup", - "VM" - ], - "severity": "Medium", - "subcategory": "stopped/deallocated VMs: check disks", - "text": "Check that the disks are really needed, if not: delete. If they are needed, find lower storage tiers or use backup -", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/manage-automation", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "d1e44a19-659d-4395-afd7-7289b835556d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", - "service": "Storage", - "services": [ - "Cost", - "Storage", - "AzurePolicy" - ], - "severity": "Medium", - "subcategory": "storage accounts lifecycle policy", - "text": "Consider moving unused storage to lower tier, with customized rule - https://learn.microsoft.com/azure/storage/blobs/lifecycle-management-policy-configure ", - "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance", - "waf": "Cost" - }, - { - "category": "Cleanup", - "checklist": "Cost Optimization Checklist", - "guid": "f2bfe456-3b0d-4834-a348-726de69c6b5c", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Tagging", - "text": "Use specific tags for temporary items with 'delete by DATE' format - and automate monthly cleanup", - "waf": "Cost" - }, - { - "category": "DB/App tuning", - "checklist": "Cost Optimization Checklist", - "guid": "2a26494b-69ba-4d37-aad5-3cc78e1d7666", - "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "DB optimization", - "text": "Plan for db optimization with the intent of downsizing the related services (and improve performance)", - "waf": "Cost" - }, - { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "7357c449-674b-45ed-a5a8-59c7733be2a1", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "App modernization", - "text": "Modernizing the app towards a microservices architecture will have the effect of letting the app scale according to the single service and not the entire stack", - "waf": "Cost" - }, - { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "a27b765a-91be-41f3-a8ef-394c2bd463cb", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "services": [ - "Cost", - "Storage", - "VM" - ], - "severity": "Medium", - "subcategory": "DB optimization", - "text": "optimizing the DB queries will increase performance and allow better right-sizing of storage and VMs", - "waf": "Cost" - }, - { - "category": "DB/APP tuning", - "checklist": "Cost Optimization Checklist", - "guid": "bac75819-59bb-491a-9ed9-0cae2cc84c37", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Demand shaping", - "text": "Using demand shaping on PaaS services will optimize costs and performances", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "b6b780cb-9fe5-4c46-989d-457a927c3874", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", - "services": [ - "Cost", - "Entra" - ], - "severity": "Medium", - "subcategory": "Advisor", - "text": "Start from the Azure Advisor page suggestions.", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "d0102cac-6aae-401e-9a84-de5de36d1d92", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "VM", - "services": [ - "Cost", - "VM" - ], - "severity": "Medium", - "subcategory": "Advisor", - "text": "Make sure advisor is configured for VM right sizing ", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "881a1bd5-d1e4-44a1-a659-d3958fd77289", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Automation", - "text": "Consider implementing IaC scripts or devops pipelines to match the cost governance process", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "b835556d-f2bf-4e45-93b0-d834a348726d", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "Cost", - "Monitor" - ], - "severity": "Medium", - "subcategory": "Automation", - "text": "Set up cost alerts for applications that have variable costs (ideally for all of them)", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "e69c6b5c-2a26-4494-a69b-ad37aad53cc7", - "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Automation", - "text": "Use Azure Automation: Automate repetitive tasks can help you save time and resources, reducing costs in the process. ", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "8e1d7666-7357-4c44-a674-b5ed85a859c7", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Automation", - "text": "Run orphaned resources workbook", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "733be2a1-a27b-4765-a91b-e1f388ef394c", - "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", - "services": [ - "Cost", - "Storage" - ], - "severity": "Medium", - "subcategory": "Baseline", - "text": "Try and establish a baseline of monthly spending and an acceptable saving target against the baseline (new services will not be optimized at this stage)", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "2bd463cb-bac7-4581-a59b-b91a3ed90cae", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "services": [ - "Cost", - "AzurePolicy" - ], - "severity": "Medium", - "subcategory": "Baseline", - "text": "Establish a cost optimization baseline by using a policy that tags every new resource as #NEW", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "2cc84c37-b6b7-480c-a9fe-5c46489d457a", - "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Baseline", - "text": "Organize resources to maximize cost insights and accountability", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "927c3874-d010-42ca-a6aa-e01e6a84de5d", - "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Budgets", - "text": "Create budgets", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "e36d1d92-881a-41bd-9d1e-44a19659d395", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Cost Analysis", - "text": "In cost analysis - use daily granularity, grouped by service name to analyze the spending of the past 3 months and identify the top 3 spenders", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "8fd77289-b835-4556-bf2b-fe4563b0d834", - "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Cost Analysis", - "text": "Check daily for cost spikes and anomalies (ideally with automatic billing exports)", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "a348726d-e69c-46b5-a2a2-6494b69bad37", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Cost Analysis", - "text": "Automate cost retrieval for deep analysis or integration", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "aad53cc7-8e1d-4766-9735-7c449674b5ed", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", - "services": [ - "Cost", - "ACR" - ], - "severity": "Medium", - "subcategory": "Free services", - "text": "Take advantage of Azure free services: Azure offers a number of free services, such as DevOps, Azure Container Registry, and Azure Logic Apps, that can help you save costs on development and operations. ", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "96c96ad8-844c-4f3b-8b38-c886ba2c0214", - "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Tagging", - "text": "Tag shared resources", - "waf": "Cost" - }, - { - "category": "Process Administration", - "checklist": "Cost Optimization Checklist", - "guid": "99014a5d-3ce5-474d-acbd-9792a6bcca2b", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Tagging", - "text": "Consider using tags to all services for cost allocation", - "waf": "Cost" - }, - { - "category": "reservations", - "checklist": "Cost Optimization Checklist", - "guid": "4fea1dbf-3dd9-45d4-ac7c-891dcb1f7d57", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "automation", - "text": "Consider Reservation automation to track and promptly react to changes", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "description": "check by searching the Meter Category Licenses in the Cost analysys", - "guid": "59ae568b-a38d-4498-9e22-13dbd7bb012f", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", - "service": "VM", - "services": [ - "Cost", - "VM", - "AzurePolicy", - "SQL" - ], - "severity": "Medium", - "subcategory": "check AHUB is applied to all Windows VMs, RHEL and SQL", - "text": "run the script on all windows VMs https://learn.microsoft.com/azure/virtual-machines/windows/hybrid-use-benefit-licensing?ref=andrewmatveychuk.com#convert-an-existing-vm-using-azure-hybrid-benefit-for-windows-server- consider implementing a policy if windows VMs are created frequently", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "7b95e06e-158e-42ea-9992-c2de6e2065b3", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", - "service": "VM", - "services": [ - "Cost", - "LoadBalancer" - ], - "severity": "Medium", - "subcategory": "Check Red Hat Licences if applicable", - "text": " this can be also put under AHUB if you already have licenses https://learn.microsoft.com/azure/virtual-machines/linux/azure-hybrid-benefit-linux?tabs=rhelpayg%2Crhelbyos%2CrhelEnablebyos%2Crhelcompliance", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "a76af4a6-91e8-4839-ada4-6667e13c1056", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", - "services": [ - "Cost", - "AppSvc" - ], - "severity": "Medium", - "subcategory": "Functions", - "text": "Saving plans will provide 17% on select app service plans", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "75c1e945-b459-4837-bf7a-e7c6d3b475a5", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", - "service": "VM", - "services": [ - "Cost", - "VM" - ], - "severity": "Medium", - "subcategory": "Planning", - "text": "Consolidate reserved VM families with flexibility option (no more than 4-5 families)", - "training": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "c7acbe49-bbe6-44dd-a9f2-e87778468d55", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", - "service": "VM", - "services": [ - "Cost", - "VM", - "ARS" - ], - "severity": "Medium", - "subcategory": "Reservations/savings plans", - "text": "Utilize Azure Reserved Instances: This feature allows you to reserve VMs for a period of 1 or 3 years, providing significant cost savings compared to PAYG prices.", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "a785c6fe-96c9-46ad-a844-cf3b2b38c886", - "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Reservations/savings plans", - "text": "Plan for Azure Savings Plans for all the workloads that are dynamic and need maximum flexibility", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "ba2c0214-9901-44a5-b3ce-574dccbd9792", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Reservations/savings plans", - "text": "Plan for Azure Reservations for all the workloads that are less dynamic and won't change much", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "a6bcca2b-4fea-41db-b3dd-95d48c7c891d", - "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", - "service": "VM", - "services": [ - "Cost", - "Storage" - ], - "severity": "Medium", - "subcategory": "Reserve storage", - "text": "Only larger disks can be reserved => 1 TiB -", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "cb1f7d57-59ae-4568-aa38-d4985e2213db", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", - "service": "VM", - "services": [ - "Cost", - "VM" - ], - "severity": "Medium", - "subcategory": "Reserve VMs with normalized and rationalized sizes", - "text": "After the right-sizing optimization", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "d7bb012f-7b95-4e06-b158-e2ea3992c2de", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", - "service": "Azure SQL", - "services": [ - "Cost", - "SQL", - "AzurePolicy" - ], - "severity": "Medium", - "subcategory": "SQL Database AHUB", - "text": "Check if applicable and enforce policy/change https://learn.microsoft.com/azure/azure-sql/azure-hybrid-benefit?view=azuresql&tabs=azure-portalhttps://learn.microsoft.com/azure/cost-management-billing/scope-level/create-sql-license-assignments?source=recommendations", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "6e2065b3-a76a-4f4a-991e-8839ada46667", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", - "service": "VM", - "services": [ - "Cost", - "VM", - "SQL" - ], - "severity": "Medium", - "subcategory": "SQL Database Reservations", - "text": "The VM + license part discount (ahub + 3YRI) is around 70% discount", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "e13c1056-75c1-4e94-9b45-9837ff7ae7c6", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", - "services": [ - "Cost" - ], - "severity": "Medium", - "subcategory": "Tracking", - "text": "Make sure you Azure Reservations and Savings plans are close to 100% utilization or make the necessary changes to reach it.", - "waf": "Cost" - }, - { - "category": "Reservations", - "checklist": "Cost Optimization Checklist", - "guid": "d3b475a5-c7ac-4be4-abbe-64dd89f2e877", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", - "services": [ - "Cost", - "AzurePolicy" - ], - "severity": "Medium", - "subcategory": "Tracking", - "text": "Make sure that your reservations usage is close to 100%. If not, either enforce an allowed SKU policy or exchange the reservation", - "waf": "Cost" - }, - { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "78468d55-a785-4c6f-b96c-96ad8844cf3b", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", - "services": [ - "Cost", - "AzurePolicy" - ], + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-bot", + "service": "Bot service", + "services": [], "severity": "Medium", - "subcategory": "Automation", - "text": "Plan and enforce a On/Off policy for production services, where possible", - "waf": "Cost" + "subcategory": "High Availablity", + "text": "Follow reliability support recommendations in Azure Bot Service", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "2b38c886-ba2c-4021-9990-14a5d3ce574d", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", - "services": [ - "Cost", - "AzurePolicy" - ], + "category": "Operations management", + "checklist": "Azure Bot Service", + "guid": "e65de8e1-3f9c-4cbd-9682-66abca264f9a", + "link": "https://learn.microsoft.com/en-us/azure/bot-service/bot-builder-concept-regionalization", + "service": "Bot service", + "services": [], "severity": "Medium", - "subcategory": "Automation", - "text": "Plan and enforce a On-Demand policy with auto-shutdown for non-production services, where possible", - "waf": "Cost" + "subcategory": "High Availablity", + "text": "Deploying bots with local data residency and regional compliance", + "waf": "Reliability" }, { - "category": "Right-sizing", - "checklist": "Cost Optimization Checklist", - "guid": "ccbd9792-a6bc-4ca2-a4fe-a1dbf3dd95d4", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", - "service": "VM", - "services": [ - "Cost", - "VM" - ], + "category": "Operations management", + "checklist": "Azure Bot Service", + "guid": "19bfe9d5-5d04-4c3c-9919-ca1b2d1215ae", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-bot#cross-region-disaster-recovery-in-multi-region-geography", + "service": "Bot service", + "services": [], "severity": "Medium", - "subcategory": "Autoscale", - "text": "Consider using a VMSS to match demand rather than flat sizing", - "waf": "Cost" + "subcategory": "High Availablity", + "text": "Azure Bot Service runs in active-active mode for both global and regional services. When an outage occurs, you don't need to detect errors or manage the service. Azure Bot Service automatically performs auto failover and auto recovery in a multi-region geographical architecture. For the EU bot regional service, Azure Bot Service provides two full regions inside Europe with active/active replication to ensure redundancy. For the global bot service, all available regions/geographies can be served as the global footprint.", + "waf": "Reliability" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "c1b1cd52-1e54-4a29-a9de-39ac0e7c28dc", - "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", - "service": "AKS", + "guid": "a95b86ad-8840-48e3-9273-4b875ba18f20", + "link": "https://learn.microsoft.com/azure/architecture/guide/multitenant/considerations/tenancy-models", + "service": "Azure Monitor", "services": [ - "Cost", - "AKS" + "Monitor", + "Cost" ], "severity": "Medium", - "subcategory": "Autoscale", - "text": "Use AKS autoscaler to match your clusters usage (make sure the pods requirements match the scaler)", + "subcategory": "Azure Monitor - enforce data collection rules", + "text": "Data collection rules in Azure Monitor -https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-rule-overview", + "training": "https://azure.microsoft.com/pricing/reservations/", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "93665720-2bff-4456-9b0d-934a359c363e", - "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", + "guid": "45901365-d38e-443f-abcb-d868266abca2", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", + "service": "Azure Backup", "services": [ + "Backup", "Cost" ], "severity": "Medium", - "subcategory": "Autoscale", - "text": "Right-size PaaS service according to average use and accomodate spikes with auto or manual scaling", + "subcategory": "Backup", + "text": "check backup instances with the underlying datasource not found", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "7dd61623-a364-4a90-9eba-e38ead53cc7d", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "guid": "64f9a19a-f29c-495d-94c6-c7919ca0f6c5", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", + "service": "VM", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Autoscale", - "text": "Plan for demand shaping where applicable", + "subcategory": "Delete/archive", + "text": "Delete or archive unassociated services (disks, nics, ip addresses etc)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "e2e8aaab-3571-4549-ab91-53d89f89dc7b", + "guid": "659d3958-fd77-4289-a835-556df2bfe456", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Autoscale", - "text": "Consider implementing a service re-scaling logic within the application", - "training": "https://learn.microsoft.com/azure/cost-management-billing/savings-plan/", + "subcategory": "Delete/archive", + "text": "Consider snooze and stop technique (snooze a service after x days, stop after 2x, delete/deallocate after 3x)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "44be3b1a-27f8-4b9e-a1be-1f38df03a822", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", - "service": "Azure Backup", + "guid": "3b0d834a-3487-426d-b69c-6b5c2a26494b", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Cost", - "Backup" + "Storage", + "Backup", + "Cost" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Move recovery points to vault-archive where applicable (Validate)", - "training": "https://azure.microsoft.com/pricing/reservations/", + "subcategory": "Delete/archive", + "text": "Delete or archive unused resources (old backups, logs, storage accounts, etc...)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "cd463cbb-bc8a-4c29-aebc-91a43da1dae2", - "link": "https://learn.microsoft.com/azure/databricks/clusters/cluster-config-best-practices#automatic-termination", - "service": "Databricks", + "guid": "69bad37a-ad53-4cc7-ae1d-76667357c449", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "service": "Azure Backup", "services": [ - "Cost", - "VM", - "LoadBalancer" + "Storage", + "ASR", + "Backup", + "Cost" ], "severity": "Medium", - "subcategory": "Databricks", - "text": "Consider using Spot VMs with fallback where possible. Consider autotermination of clusters.", + "subcategory": "Delete/archive", + "text": "Consider a good balance between site recovery storage and backup for non mission critical applications", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "cc881470-607c-41cc-a0e6-14658dd458e9", - "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", - "service": "Azure Functions", + "guid": "674b5ed8-5a85-49c7-933b-e2a1a27b765a", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/direct-ea-administration#manage-notification-contacts", + "service": "Azure Monitor", "services": [ + "Monitor", "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "Functions - Reuse connections", - "training": "https://learn.microsoft.com/azure/cost-management-billing/reservations/reservation-apis?toc=%2Fazure%2Fcost-management-billing%2Ftoc.json", + "subcategory": "Log Analytics retention for workspaces", + "text": "Check spending and savings opportunities among the 40 different log analytics workspaces- use different retention and data collection for nonprod workspaces-create daily cap for awareness and tier sizing - If you do set a daily cap, in addition to creating an alert when the cap is reached,ensure that you also create an alert rule to be notified when some percentage has been reached (90% for example). - consider workspace transformation if possible - https://learn.microsoft.com/azure/azure-monitor/essentials/data-collection-transformations#workspace-transformation-dcr ", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/understand-work-scopes", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "27139b82-1102-4dbd-9eaf-11e6f843e52f", - "link": "https://learn.microsoft.com/azure/automation/update-management/overview", - "service": "Azure Functions", + "guid": "91be1f38-8ef3-494c-8bd4-63cbbac75819", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "service": "Azure Monitor", "services": [ + "Storage", + "AzurePolicy", "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "Functions - Cache data locally", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", + "subcategory": "Policy", + "text": "Enforce a purging log policy and automation (if needed, logs can be moved to cold storage)", + "training": "https://www.youtube.com/watch?v=nHQYcYGKuyw", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "4722d928-c1b1-4cd5-81e5-4a29b9de39ac", - "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", - "service": "Azure Functions", + "guid": "59bb91a3-ed90-4cae-8cc8-4c37b6b780cb", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "Cost", - "Storage" + "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "Functions - Cold starts-Use the 'Run from package' functionality. This way, the code is downloaded as a single zip file. This can, for example, result in significant improvements with Javascript functions, which have a lot of node modules.Use language specific tools to reduce the package size, for example, tree shaking Javascript applications.", - "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", + "subcategory": "Run orphaned resources workbook - delete or snooze ghost items", + "text": "https://github.com/dolevshor/azure-orphan-resources", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "0e7c28dc-9366-4572-82bf-f4564b0d934a", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", - "service": "Azure Functions", + "guid": "9fe5c464-89d4-457a-a27c-3874d0102cac", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "Functions - Keep your functions warm", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "subcategory": "Shutdown/deallocate", + "text": "Shutdown underutilized instances", + "training": "https://learn.microsoft.com/azure/cost-management-billing/understand/analyze-unexpected-charges", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "359c363e-7dd6-4162-9a36-4a907ebae38e", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Azure Functions", + "guid": "6aae01e6-a84d-4e5d-b36d-1d92881a1bd5", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "service": "VM", "services": [ + "Storage", + "VM", + "Backup", "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "When using autoscale with different functions, there might be one driving all the autoscale for all the resources - consider moving it to a separate consumption plan (and consider higher plan for CPU)", + "subcategory": "stopped/deallocated VMs: check disks", + "text": "Check that the disks are really needed, if not: delete. If they are needed, find lower storage tiers or use backup -", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/manage-automation", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "ad53cc7d-e2e8-4aaa-a357-1549ab9153d8", - "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", - "service": "Azure Functions", + "guid": "d1e44a19-659d-4395-afd7-7289b835556d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", + "service": "Storage", "services": [ + "Storage", + "AzurePolicy", "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "Function apps in a given plan are all scaled together, so any issues with scaling can affect all apps in the plan.", + "subcategory": "storage accounts lifecycle policy", + "text": "Consider moving unused storage to lower tier, with customized rule - https://learn.microsoft.com/azure/storage/blobs/lifecycle-management-policy-configure ", + "training": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Cleanup", "checklist": "Cost Optimization Checklist", - "guid": "9f89dc7b-44be-43b1-a27f-8b9e91be1f38", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", - "service": "Azure Functions", + "guid": "f2bfe456-3b0d-4834-a348-726de69c6b5c", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Functions", - "text": "Am I billed for 'await time'? This question is typically asked in the context of a C# function that does an async operation and waits for the result, e.g. await Task.Delay(1000) or await client.GetAsync('http://google.com'). The answer is yes - the GB second calculation is based on the start and end time of the function and the memory usage over that period. What actually happens over that time in terms of CPU activity is not factored into the calculation.One exception to this rule is if you are using durable functions. You are not billed for time spent at awaits in orchestrator functions.apply demand shaping techinques where possible (dev environments?) https://github.com/Azure-Samples/functions-csharp-premium-scaler", + "subcategory": "Tagging", + "text": "Use specific tags for temporary items with 'delete by DATE' format - and automate monthly cleanup", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "DB/App tuning", "checklist": "Cost Optimization Checklist", - "guid": "df03a822-cd46-43cb-abc8-ac299ebc91a4", - "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", + "guid": "2a26494b-69ba-4d37-aad5-3cc78e1d7666", + "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Evaluate your network topology against networking costs and where applicable reduce the egress and peering data", + "subcategory": "DB optimization", + "text": "Plan for db optimization with the intent of downsizing the related services (and improve performance)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "DB/APP tuning", "checklist": "Cost Optimization Checklist", - "guid": "3da1dae2-cc88-4147-8607-c1cca0e61465", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "service": "Front Door", + "guid": "7357c449-674b-45ed-a5a8-59c7733be2a1", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Cost", - "EventHubs", - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Frontdoor - Turn off the default homepageIn the application settings of your App, set AzureWebJobsDisableHomepage to true. This will return a 204 (No Content) to the PoP so only header data is returned.", + "subcategory": "App modernization", + "text": "Modernizing the app towards a microservices architecture will have the effect of letting the app scale according to the single service and not the entire stack", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "DB/APP tuning", "checklist": "Cost Optimization Checklist", - "guid": "8dd458e9-2713-49b8-8110-2dbd6eaf11e6", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", - "service": "Front Door", + "guid": "a27b765a-91be-41f3-a8ef-394c2bd463cb", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Cost", - "AppSvc", - "FrontDoor" + "Storage", + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "Networking", - "text": "Frontdoor - Route to something that returns nothing. Either set up a Function, Function Proxy, or add a route in your WebApp that returns 200 (OK) and sends no or minimal content. The advantage of this is you will be able to log out when it is called.", + "subcategory": "DB optimization", + "text": "optimizing the DB queries will increase performance and allow better right-sizing of storage and VMs", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "DB/APP tuning", "checklist": "Cost Optimization Checklist", - "guid": "f843e52f-4722-4d92-ac1b-1cd521e54a29", - "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", + "guid": "bac75819-59bb-491a-9ed9-0cae2cc84c37", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "PaaS", - "text": "Consider using free tiers where applicable for all non-production environments", + "subcategory": "Demand shaping", + "text": "Using demand shaping on PaaS services will optimize costs and performances", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "b9de39ac-0e7c-428d-a936-657202bff456", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", + "guid": "b6b780cb-9fe5-4c46-989d-457a927c3874", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/naming-and-tagging", "services": [ + "Entra", "Cost" ], "severity": "Medium", - "subcategory": "Serverless", - "text": "Using serverless patterns for spikes can help keeping costs down", + "subcategory": "Advisor", + "text": "Start from the Azure Advisor page suggestions.", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "7e31c67d-68cf-46a6-8a11-94956d697dc3", - "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", - "service": "Storage", + "guid": "d0102cac-6aae-401e-9a84-de5de36d1d92", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "VM", "services": [ - "Cost", - "Storage" + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Consider archiving tiers for less used data", + "subcategory": "Advisor", + "text": "Make sure advisor is configured for VM right sizing ", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "a2ed27b2-d186-4f1a-8252-bddde68a487c", - "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", - "service": "VM", + "guid": "881a1bd5-d1e4-44a1-a659-d3958fd77289", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost", - "Storage" + "Cost" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Check disk sizes where the size does not match the tier (i.e. A 513 GiB disk will pay a P30 (1TiB) and consider resizing", + "subcategory": "Automation", + "text": "Consider implementing IaC scripts or devops pipelines to match the cost governance process", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "dec4861b-c3bc-410a-b77e-26e4d5a3bec2", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", - "service": "Storage", + "guid": "b835556d-f2bf-4e45-93b0-d834a348726d", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost", - "Storage" + "Monitor", + "Cost" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Consider using standard SSD rather than Premium or Ultra where possible", + "subcategory": "Automation", + "text": "Set up cost alerts for applications that have variable costs (ideally for all of them)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "c4e2436b-1336-4db5-9f17-960eee0bdf5c", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", - "service": "Storage", + "guid": "e69c6b5c-2a26-4494-a69b-ad37aad53cc7", + "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", "services": [ - "Cost", - "Storage" + "Cost" ], "severity": "Medium", - "subcategory": "Storage", - "text": "For storage accounts, make sure that the chosen tier is not adding up transaction charges (it might be cheaper to move to the next tier)", + "subcategory": "Automation", + "text": "Use Azure Automation: Automate repetitive tasks can help you save time and resources, reducing costs in the process. ", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "c2efc5d7-61d4-41d2-900b-b47a393a040f", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", - "service": "Site Recovery", + "guid": "8e1d7666-7357-4c44-a674-b5ed85a859c7", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost", - "Storage", - "ASR" + "Cost" ], "severity": "Medium", - "subcategory": "Storage", - "text": "For ASR, consider using Standard SSD disks if the RPO/RTO and replication throughput allow it", + "subcategory": "Automation", + "text": "Run orphaned resources workbook", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "d3294798-b118-48b2-a5a4-6ceb544451e1", - "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", - "service": "Storage", + "guid": "733be2a1-a27b-4765-a91b-e1f388ef394c", + "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "services": [ - "Cost", - "Storage" + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "storage", - "text": "Storage accounts: check hot tier and/or GRS necessary", + "subcategory": "Baseline", + "text": "Try and establish a baseline of monthly spending and an acceptable saving target against the baseline (new services will not be optimized at this stage)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "92d34429-3c76-4286-97a5-51c5b04e4f18", - "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", - "service": "VM", + "guid": "2bd463cb-bac7-4581-a59b-b91a3ed90cae", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", "services": [ - "Cost", - "Storage" + "AzurePolicy", + "Cost" ], "severity": "Medium", - "subcategory": "Storage", - "text": "Disks - validate use of Premium SSD disks everywhere: for example, non-prod could swap to Standard SSD or on-demand Premium SSD ", + "subcategory": "Baseline", + "text": "Establish a cost optimization baseline by using a policy that tags every new resource as #NEW", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "54387e5c-ed12-46cd-832a-f5b2fc6998a5", - "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", - "service": "Synapse", + "guid": "2cc84c37-b6b7-480c-a9fe-5c46489d457a", + "link": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management-config", "services": [ - "Cost", - "EventHubs", - "Monitor" + "Cost" ], "severity": "Medium", - "subcategory": "Synapse", - "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks.", + "subcategory": "Baseline", + "text": "Organize resources to maximize cost insights and accountability", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "35e33789-7e31-4c67-b68c-f6a62a119495", - "link": "https://learn.microsoft.com/azure/virtual-machines/availability", - "service": "Synapse", + "guid": "927c3874-d010-42ca-a6aa-e01e6a84de5d", + "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", "services": [ - "Cost", - "Storage" + "Cost" ], "severity": "Medium", - "subcategory": "Synapse", - "text": "Export cost data to a storage account for additional data analysis.", + "subcategory": "Budgets", + "text": "Create budgets", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "6d697dc3-a2ed-427b-8d18-6f1a1252bddd", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "service": "Synapse", + "guid": "e36d1d92-881a-41bd-9d1e-44a19659d395", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", "services": [ - "Cost", - "SQL" + "Cost" ], "severity": "Medium", - "subcategory": "Synapse", - "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use.", + "subcategory": "Cost Analysis", + "text": "In cost analysis - use daily granularity, grouped by service name to analyze the spending of the past 3 months and identify the top 3 spenders", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "e68a487c-dec4-4861-ac3b-c10ae77e26e4", - "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", - "service": "Synapse", + "guid": "8fd77289-b835-4556-bf2b-fe4563b0d834", + "link": "https://learn.microsoft.com/azure/active-directory/hybrid/how-to-connect-sync-staging-server", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Synapse", - "text": "Enable the serverless Apache Spark automatic pause feature and set your timeout value accordingly.", + "subcategory": "Cost Analysis", + "text": "Check daily for cost spikes and anomalies (ideally with automatic billing exports)", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "d5a3bec2-c4e2-4436-a133-6db55f17960e", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", - "service": "Synapse", + "guid": "a348726d-e69c-46b5-a2a2-6494b69bad37", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", "services": [ "Cost" ], "severity": "Medium", - "subcategory": "Synapse", - "text": "Create multiple Apache Spark pool definitions of various sizes.", + "subcategory": "Cost Analysis", + "text": "Automate cost retrieval for deep analysis or integration", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "ee0bdf5c-c2ef-4c5d-961d-41d2500bb47a", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", - "service": "Synapse", + "guid": "aad53cc7-8e1d-4766-9735-7c449674b5ed", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", "services": [ + "ACR", "Cost" ], "severity": "Medium", - "subcategory": "Synapse", - "text": "Purchase Azure Synapse commit units (SCU) for one year with a pre-purchase plan to save on your Azure Synapse Analytics costs.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Free services", + "text": "Take advantage of Azure free services: Azure offers a number of free services, such as DevOps, Azure Container Registry, and Azure Logic Apps, that can help you save costs on development and operations. ", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "393a040f-d329-4479-ab11-88b2c5a46ceb", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", - "service": "VM", + "guid": "96c96ad8-844c-4f3b-8b38-c886ba2c0214", + "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", "services": [ - "Cost", - "VM" + "Cost" ], "severity": "Medium", - "subcategory": "VM", - "text": "Use Spot VMs for interruptible jobs: These are VMs that can be bid on and purchased at a discounted price, providing a cost-effective solution for non-critical workloads.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "Tagging", + "text": "Tag shared resources", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Process Administration", "checklist": "Cost Optimization Checklist", - "guid": "544451e1-92d3-4442-a3c7-628637a551c5", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "service": "VM", + "guid": "99014a5d-3ce5-474d-acbd-9792a6bcca2b", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", "services": [ - "Cost", - "VM" + "Cost" ], "severity": "Medium", - "subcategory": "VM", - "text": "Right-sizing all VMs", + "subcategory": "Tagging", + "text": "Consider using tags to all services for cost allocation", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "reservations", "checklist": "Cost Optimization Checklist", - "guid": "b04e4f18-5438-47e5-aed1-26cd032af5b2", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", - "service": "VM", + "guid": "4fea1dbf-3dd9-45d4-ac7c-891dcb1f7d57", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", "services": [ - "Cost", - "VM" + "Cost" ], "severity": "Medium", - "subcategory": "VM", - "text": "Swap VM sized with normalized and most recent sizes", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "automation", + "text": "Consider Reservation automation to track and promptly react to changes", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Reservations", "checklist": "Cost Optimization Checklist", - "guid": "fc6998a5-35e3-4378-a7e3-1c67d68cf6a6", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "description": "check by searching the Meter Category Licenses in the Cost analysys", + "guid": "59ae568b-a38d-4498-9e22-13dbd7bb012f", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", "service": "VM", "services": [ - "Cost", + "SQL", "VM", - "Monitor" + "AzurePolicy", + "Cost" ], "severity": "Medium", - "subcategory": "VM", - "text": "right-sizing VMs - start with monitoring usage below 5% and then work up to 40%", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "subcategory": "check AHUB is applied to all Windows VMs, RHEL and SQL", + "text": "run the script on all windows VMs https://learn.microsoft.com/azure/virtual-machines/windows/hybrid-use-benefit-licensing?ref=andrewmatveychuk.com#convert-an-existing-vm-using-azure-hybrid-benefit-for-windows-server- consider implementing a policy if windows VMs are created frequently", "waf": "Cost" }, { - "category": "Right-sizing", + "category": "Reservations", "checklist": "Cost Optimization Checklist", - "guid": "2a119495-6d69-47dc-9a2e-d27b2d186f1a", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "guid": "7b95e06e-158e-42ea-9992-c2de6e2065b3", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "service": "VM", "services": [ - "Cost", - "VM" + "LoadBalancer", + "Cost" ], "severity": "Medium", - "subcategory": "VM", - "text": "Containerizing an application can improve VM density and save money on scaling it", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "subcategory": "Check Red Hat Licences if applicable", + "text": " this can be also put under AHUB if you already have licenses https://learn.microsoft.com/azure/virtual-machines/linux/azure-hybrid-benefit-linux?tabs=rhelpayg%2Crhelbyos%2CrhelEnablebyos%2Crhelcompliance", "waf": "Cost" }, { - "category": "BC and DR", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "a76af4a6-91e8-4839-ada4-6667e13c1056", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", "services": [ - "ACR" + "AppSvc", + "Cost" ], - "severity": "High", - "subcategory": "High Availability", - "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Functions", + "text": "Saving plans will provide 17% on select app service plans", + "waf": "Cost" }, { - "category": "BC and DR", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "75c1e945-b459-4837-bf7a-e7c6d3b475a5", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", + "service": "VM", "services": [ - "Storage" + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "High Availability", - "text": "Configure data persistence for an Azure Cache for Redis instance. Because your cache data is stored in memory, a rare and unplanned failure of multiple nodes can cause all the data to be dropped. To avoid losing data completely, Redis persistence allows you to take periodic snapshots of in-memory data, and store it to your storage account.", - "waf": "Reliability" + "subcategory": "Planning", + "text": "Consolidate reserved VM families with flexibility option (no more than 4-5 families)", + "training": "https://learn.microsoft.com/azure/automation/automation-solution-vm-management", + "waf": "Cost" }, { - "category": "BC and DR", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "c7acbe49-bbe6-44dd-a9f2-e87778468d55", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", + "service": "VM", "services": [ - "Storage" + "ARS", + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "High Availability", - "text": "Use Geo-redundant storage account to persist Azure Cache for Redis data, or zonally redundant where geo-redundancy is not available", - "waf": "Reliability" + "subcategory": "Reservations/savings plans", + "text": "Utilize Azure Reserved Instances: This feature allows you to reserve VMs for a period of 1 or 3 years, providing significant cost savings compared to PAYG prices.", + "waf": "Cost" }, { - "category": "BC and DR", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "a785c6fe-96c9-46ad-a844-cf3b2b38c886", + "link": "https://azure.microsoft.com/resources/achieving-compliant-data-residency-and-security-with-azure/", "services": [ - "ASR" + "Cost" ], "severity": "Medium", - "subcategory": "High Availability", - "text": "Configure passive geo-replication for Premium Azure Cache for Redis instances. Geo-replication is a mechanism for linking two or more Azure Cache for Redis instances, typically spanning two Azure regions. Geo-replication is designed mainly for cross-region disaster recovery. Two Premium tier cache instances are connected through geo-replication in a way that provides reads and writes to your primary cache, and that data is replicated to the secondary cache.", - "waf": "Reliability" + "subcategory": "Reservations/savings plans", + "text": "Plan for Azure Savings Plans for all the workloads that are dynamic and need maximum flexibility", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.Cdn/profiles/secrets' | extend frontDoorId = substring(id, 0, indexof(id, '/secrets')) | where properties.parameters.type =~ 'CustomerCertificate' | extend compliant = properties.parameters.useLatestVersion == true | project compliant, id=frontDoorId, certificateName = name | distinct id, certificateName, compliant", - "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "ba2c0214-9901-44a5-b3ce-574dccbd9792", + "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", "services": [ - "AKV", - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "If you use customer-managed TLS certificates with Azure Front Door, use the 'Latest' certificate version. Reduce the risk of outages caused by manual certificate renewal.", - "waf": "Operations" + "subcategory": "Reservations/savings plans", + "text": "Plan for Azure Reservations for all the workloads that are less dynamic and won't change much", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.cdn/profiles' and sku has 'AzureFrontDoor' | project name, cdnprofileid=tolower(id), tostring(tags), resourceGroup, subscriptionId,skuname=tostring(sku.name) | join kind= fullouter ( cdnresources | where type == 'microsoft.cdn/profiles/securitypolicies' | extend wafpolicyid=tostring(properties['parameters']['wafPolicy']['id']) | extend splitid=split(id, '/') | extend cdnprofileid=tolower(strcat_array(array_slice(splitid, 0, 8), '/')) | project secpolname=name, cdnprofileid, wafpolicyid ) on cdnprofileid | project name, cdnprofileid, secpolname, wafpolicyid,skuname | join kind = fullouter ( resources | where type == 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | extend managedrulesenabled=iff(tostring(properties.managedRules.managedRuleSets) != '[]', true, false), enabledState = tostring(properties.policySettings.enabledState) | project afdwafname=name, managedrulesenabled, wafpolicyid=id, enabledState, tostring(tags) ) on wafpolicyid | where name != '' | summarize associatedsecuritypolicies=countif(secpolname != ''), wafswithmanagedrules=countif(managedrulesenabled == 1) by name, id=cdnprofileid, tags,skuname | extend compliant = (associatedsecuritypolicies > 0 and wafswithmanagedrules > 0) | project id, compliant", - "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "a6bcca2b-4fea-41db-b3dd-95d48c7c891d", + "link": "https://learn.microsoft.com/azure/active-directory-domain-services/overview", + "service": "VM", "services": [ - "FrontDoor", - "AzurePolicy", - "WAF" + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use Azure Front Door with WAF policies to deliver and help protect global HTTP/S apps that span multiple Azure regions.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "subcategory": "Reserve storage", + "text": "Only larger disks can be reserved => 1 TiB -", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "link": "https://learn.microsoft.com/azure/frontdoor/origin-security?tabs=application-gateway&pivots=front-door-standard-premium#example-configuration", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "cb1f7d57-59ae-4568-aa38-d4985e2213db", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain", + "service": "VM", "services": [ - "AppGW", - "FrontDoor", - "AzurePolicy", - "WAF" + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "When using Front Door and Application Gateway to help protect HTTP/S apps, use WAF policies in Front Door. Lock down Application Gateway to receive traffic only from Front Door.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Security" + "subcategory": "Reserve VMs with normalized and rationalized sizes", + "text": "After the right-sizing optimization", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | project policyName=name, policyId=id,policySku=sku.name, links=properties.securityPolicyLinks, enabledState=properties.policySettings.enabledState, mode=properties.policySettings.mode | mvexpand links | extend securityPolicy=links.id | extend securityPolicyParts=split(securityPolicy, '/') | extend profileId=strcat_array(array_slice(securityPolicyParts, 0, -3), '/') | project id=profileId, compliant=((enabledState=='Enabled') and (mode=='Prevention')), enabledState, mode", - "guid": "ae248989-b306-4591-9186-de482e3f0f0e", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "d7bb012f-7b95-4e06-b158-e2ea3992c2de", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", + "service": "Azure SQL", "services": [ - "FrontDoor", + "SQL", "AzurePolicy", - "WAF" - ], - "severity": "High", - "subcategory": "Front Door", - "text": "Deploy your WAF policy for Front Door in 'Prevention' mode' so that Web Application Firewall takes appropriate action to allow or deny traffic.", - "waf": "Security" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/origins' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend compliant = properties['hostName'] !endswith '.trafficmanager.net' | project compliant, id=frontDoorId", - "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "service": "Front Door", - "services": [ - "EventHubs", - "FrontDoor", - "TrafficManager" - ], - "severity": "High", - "subcategory": "Front Door", - "text": "Avoid placing Traffic Manager behind Front Door.", - "waf": "Security" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/origins' | extend frontDoorId = substring(id, 0, indexof(id, '/origins')) | extend compliant = isempty(properties.originHostHeader) or (tostring(properties.hostName) =~ tostring(properties.originHostHeader)) | project id=frontDoorId, originName = name, compliant", - "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", - "service": "Front Door", - "services": [ - "FrontDoor" - ], - "severity": "High", - "subcategory": "Front Door", - "text": "Use the same domain name on Azure Front Door and your origin. Mismatched host names can cause subtle bugs.", - "waf": "Security" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/origins' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend originGroupId = substring(id, 0, indexof(id, '/origins')) | join kind=inner (cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend originGroupName = name | extend hasHealthProbe = isnotnull(properties.healthProbeSettings)) on $left.originGroupId == $right.id | summarize numberOrigins = count() by originGroupId, subscriptionId, frontDoorId, hasHealthProbe, originGroupName | extend compliant = not(numberOrigins == 1 and hasHealthProbe) | project id = frontDoorId, compliant", - "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "service": "Front Door", - "services": [ - "FrontDoor" - ], - "severity": "Low", - "subcategory": "Front Door", - "text": "Disable health probes when there is only one origin in an Azure Front Door origin group.", - "waf": "Performance" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", - "service": "Front Door", - "services": [ - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Select good health probe endpoints for Azure Front Door. Consider building health endpoints that check all of your application's dependencies.", - "waf": "Reliability" - }, - { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups/')) | extend compliant = (isnull(properties['healthProbeSettings']['probeRequestType']) or toupper(properties['healthProbeSettings']['probeRequestType']) == 'HEAD') | project compliant, id=frontDoorId", - "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", - "service": "Front Door", - "services": [ - "FrontDoor" - ], - "severity": "Low", - "subcategory": "Front Door", - "text": "Use HEAD health probes with Azure Front Door, to reduce the traffic that Front Door sends to your application.", - "waf": "Performance" + "subcategory": "SQL Database AHUB", + "text": "Check if applicable and enforce policy/change https://learn.microsoft.com/azure/azure-sql/azure-hybrid-benefit?view=azuresql&tabs=azure-portalhttps://learn.microsoft.com/azure/cost-management-billing/scope-level/create-sql-license-assignments?source=recommendations", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/customdomains' | extend frontDoorId = substring(id, 0, indexof(id, '/customdomains')) | extend compliant = (isnull(properties['tlsSettings']['certificateType']) or tolower(properties['tlsSettings']['certificateType']) =~ 'customercertificate') | project compliant, id = frontDoorId", - "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "6e2065b3-a76a-4f4a-991e-8839ada46667", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", + "service": "VM", "services": [ - "Cost", - "AKV", - "FrontDoor" + "VM", + "SQL", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "SQL Database Reservations", + "text": "The VM + license part discount (ahub + 3YRI) is around 70% discount", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "e13c1056-75c1-4e94-9b45-9837ff7ae7c6", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#managed-identities", "services": [ - "FrontDoor", - "WAF" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Define your Azure Front Door WAF configuration as code. By using code, you can more easily adopt new rule set version and gain additional protection.", - "waf": "Operations" + "subcategory": "Tracking", + "text": "Make sure you Azure Reservations and Savings plans are close to 100% utilization or make the necessary changes to reach it.", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type == 'microsoft.cdn/profiles/afdendpoints/routes' | extend frontDoorId = substring(id, 0, indexof(id, '/afdendpoints')) | extend forwardingProtocol=tostring(properties.forwardingProtocol),supportedProtocols=properties.supportedProtocols,httpsRedirect=properties.httpsRedirect | extend compliant = forwardingProtocol =~ 'httpsonly' and (supportedProtocols has 'https' or httpsRedirect =~ 'enabled') | project id = frontDoorId, compliant", - "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", - "service": "Front Door", + "category": "Reservations", + "checklist": "Cost Optimization Checklist", + "guid": "d3b475a5-c7ac-4be4-abbe-64dd89f2e877", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", "services": [ - "FrontDoor" + "AzurePolicy", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Use end-to-end TLS with Azure Front Door. Use TLS for connections from your clients to Front Door, and from Front Door to your origin.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Tracking", + "text": "Make sure that your reservations usage is close to 100%. If not, either enforce an allowed SKU policy or exchange the reservation", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type == 'microsoft.cdn/profiles/afdendpoints/routes' | extend frontDoorId = substring(id, 0, indexof(id, '/afdendpoints')) | extend forwardingProtocol=tostring(properties.forwardingProtocol),supportedProtocols=properties.supportedProtocols,httpsRedirect=properties.httpsRedirect | extend compliant = httpsRedirect =~ 'enabled' | project id = frontDoorId, compliant", - "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "78468d55-a785-4c6f-b96c-96ad8844cf3b", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-create-roles-and-resource-roles-review", "services": [ - "FrontDoor" + "AzurePolicy", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use HTTP to HTTPS redirection with Azure Front Door. Support older clients by redirecting them to an HTTPS request automatically.", - "waf": "Security" + "subcategory": "Automation", + "text": "Plan and enforce a On/Off policy for production services, where possible", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | project policyName=name, policyId=id,policySku=sku.name, links=properties.securityPolicyLinks, enabledState=properties.policySettings.enabledState, mode=properties.policySettings.mode | mvexpand links | extend securityPolicy=links.id | extend securityPolicyParts=split(securityPolicy, '/') | extend profileId=strcat_array(array_slice(securityPolicyParts, 0, -3), '/') | project id=profileId, compliant=((enabledState=~'Enabled') and (mode=~'Prevention')), enabledState, mode", - "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "2b38c886-ba2c-4021-9990-14a5d3ce574d", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "services": [ - "FrontDoor", - "WAF" + "AzurePolicy", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Enable the Azure Front Door WAF. Protect your application from a range of attacks.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Automation", + "text": "Plan and enforce a On-Demand policy with auto-shutdown for non-production services, where possible", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "ccbd9792-a6bc-4ca2-a4fe-a1dbf3dd95d4", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", + "service": "VM", "services": [ - "FrontDoor", - "WAF" + "VM", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Tune the Azure Front Door WAF for your workload by configuring the WAF in Detection mode to reduce and fix false positive detections.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Autoscale", + "text": "Consider using a VMSS to match demand rather than flat sizing", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "c1b1cd52-1e54-4a29-a9de-39ac0e7c28dc", + "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", + "service": "AKS", "services": [ - "FrontDoor", - "AzurePolicy", - "WAF" + "AKS", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Enable request body inspection feature enabled in Azure Front Door WAF policy.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Autoscale", + "text": "Use AKS autoscaler to match your clusters usage (make sure the pods requirements match the scaler)", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "93665720-2bff-4456-9b0d-934a359c363e", + "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", "services": [ - "FrontDoor", - "WAF" + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Enable the Azure Front Door WAF default rule sets. The default rule sets detect and block common attacks.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Autoscale", + "text": "Right-size PaaS service according to average use and accomodate spikes with auto or manual scaling", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "7dd61623-a364-4a90-9eba-e38ead53cc7d", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "services": [ - "FrontDoor", - "WAF" + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Enable the Azure Front Door WAF bot protection rule set. The bot rules detect good and bad bots.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Autoscale", + "text": "Plan for demand shaping where applicable", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "e2e8aaab-3571-4549-ab91-53d89f89dc7b", "services": [ - "FrontDoor", - "WAF" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use the latest Azure Front Door WAF rule set version. Rule set updates are regularly updated to take account of the current threat landscape.", - "waf": "Security" + "subcategory": "Autoscale", + "text": "Consider implementing a service re-scaling logic within the application", + "training": "https://learn.microsoft.com/azure/cost-management-billing/savings-plan/", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "b9620385-1cde-418f-914b-a84a06982ffc", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "44be3b1a-27f8-4b9e-a1be-1f38df03a822", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", + "service": "Azure Backup", "services": [ - "FrontDoor", - "WAF" + "Backup", + "Cost" ], - "severity": "Medium", - "subcategory": "Front Door", - "text": "Add rate limiting to the Azure Front Door WAF. Rate limiting blocks clients accidentally or intentionally sending large amounts of traffic in a short period of time.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Backup", + "text": "Move recovery points to vault-archive where applicable (Validate)", + "training": "https://azure.microsoft.com/pricing/reservations/", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "cd463cbb-bc8a-4c29-aebc-91a43da1dae2", + "link": "https://learn.microsoft.com/azure/databricks/clusters/cluster-config-best-practices#automatic-termination", + "service": "Databricks", "services": [ - "FrontDoor", - "WAF" + "LoadBalancer", + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use a high threshold for Azure Front Door WAF rate limits. High rate limit thresholds avoid blocking legitimate traffic, while still providing protection against extremely high numbers of requests that might overwhelm your infrastructure.", - "waf": "Security" + "subcategory": "Databricks", + "text": "Consider using Spot VMs with fallback where possible. Consider autotermination of clusters.", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "cc881470-607c-41cc-a0e6-14658dd458e9", + "link": "https://learn.microsoft.com/azure/governance/policy/how-to/guest-configuration-create", + "service": "Azure Functions", "services": [ - "FrontDoor" + "Cost" ], - "severity": "Low", - "subcategory": "Front Door", - "text": "If you are not expecting traffic from all geographical regions, use geo-filters to block traffic from non-expected countries.", - "waf": "Security" + "severity": "Medium", + "subcategory": "Functions", + "text": "Functions - Reuse connections", + "training": "https://learn.microsoft.com/azure/cost-management-billing/reservations/reservation-apis?toc=%2Fazure%2Fcost-management-billing%2Ftoc.json", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "00acd8a9-6975-414f-8491-2be6309893b8", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "27139b82-1102-4dbd-9eaf-11e6f843e52f", + "link": "https://learn.microsoft.com/azure/automation/update-management/overview", + "service": "Azure Functions", "services": [ - "FrontDoor", - "WAF" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Specify the unknown (ZZ) location when geo-filtering traffic with the Azure Front Door WAF. Avoid accidentally blocking legitimate requests when IP addresses can't be geo-matched.", - "waf": "Security" + "subcategory": "Functions", + "text": "Functions - Cache data locally", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-compute-resources/", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "4cea4050-7946-4a7c-89e6-b021b73c352d", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "4722d928-c1b1-4cd5-81e5-4a29b9de39ac", + "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", + "service": "Azure Functions", "services": [ - "FrontDoor", - "Monitor", - "WAF" + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Capture logs and metrics by turning on Diagnostic Settings. Include resource activity logs, access logs, health probe logs, and WAF logs. Set up alerts.", - "waf": "Operations" + "subcategory": "Functions", + "text": "Functions - Cold starts-Use the 'Run from package' functionality. This way, the code is downloaded as a single zip file. This can, for example, result in significant improvements with Javascript functions, which have a lot of node modules.Use language specific tools to reduce the package size, for example, tree shaking Javascript applications.", + "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "845f5f91-9c21-4674-a725-5ce890850e20", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "0e7c28dc-9366-4572-82bf-f4564b0d934a", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", + "service": "Azure Functions", "services": [ - "Sentinel", - "FrontDoor", - "WAF" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Send Azure Front Door WAF logs to Microsoft Sentinel.", - "waf": "Operations" + "subcategory": "Functions", + "text": "Functions - Keep your functions warm", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "3bb0a854-ea3d-4212-bd8e-3f0cb7792b02", - "link": "https://learn.microsoft.com/azure/frontdoor/routing-methods", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "359c363e-7dd6-4162-9a36-4a907ebae38e", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Azure Functions", "services": [ - "Backup", - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Choose a routing method that supports your deployment strategy. The weighted method, which distributes traffic based on the configured weight coefficient, supports active-active models. A priority-based value that configures the primary region to receive all traffic and send traffic to the secondary region as a backup supports active-passive models. Combine the preceding methods with latency so that the origin with the lowest latency receives traffic.", - "waf": "Reliability" + "subcategory": "Functions", + "text": "When using autoscale with different functions, there might be one driving all the autoscale for all the resources - consider moving it to a separate consumption plan (and consider higher plan for CPU)", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend healthprobe=tostring(properties.healthProbeSettings) | project origingroupname=name, id, tags, resourceGroup, subscriptionId, healthprobe, frontDoorId | join ( cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/Origins' | extend origingroupname = tostring(properties.originGroupName) ) on origingroupname | summarize origincount=count(), enabledhealthprobecount=countif(healthprobe != '') by origingroupname, id, tostring(tags), resourceGroup, subscriptionId, frontDoorId | extend compliant = origincount > 1 | project id = frontDoorId, compliant", - "guid": "c3a769e4-cc78-40a9-b36a-f9bcab19ec2d", - "link": "https://learn.microsoft.com/azure/frontdoor/quickstart-create-front-door", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "ad53cc7d-e2e8-4aaa-a357-1549ab9153d8", + "link": "https://learn.microsoft.com/azure/service-health/alerts-activity-log-service-notifications-portal", + "service": "Azure Functions", "services": [ - "FrontDoor" + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Support redundancy by having multiple origins in one or more back-end pools. Always have redundant instances of your application and make sure each instance exposes an endpoint or origin. You can place those origins in one or more back-end pools.", - "waf": "Reliability" + "severity": "Medium", + "subcategory": "Functions", + "text": "Function apps in a given plan are all scaled together, so any issues with scaling can affect all apps in the plan.", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "999852be-2137-4179-8fc3-30d1df6fed1d", - "link": "https://learn.microsoft.com/azure/frontdoor/troubleshoot-issues#troubleshooting-steps", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "9f89dc7b-44be-43b1-a27f-8b9e91be1f38", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/action-groups", + "service": "Azure Functions", "services": [ - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Set a timeout on forwarding requests to the back end. Adjust the timeout setting according to your endpoints' needs. If you don't, Azure Front Door might close the connection before the origin sends the response. You can also lower the default timeout for Azure Front Door if all of your origins have a shorter timeout.", - "waf": "Reliability" + "subcategory": "Functions", + "text": "Am I billed for 'await time'? This question is typically asked in the context of a C# function that does an async operation and waits for the result, e.g. await Task.Delay(1000) or await client.GetAsync('http://google.com'). The answer is yes - the GB second calculation is based on the start and end time of the function and the memory usage over that period. What actually happens over that time in terms of CPU activity is not factored into the calculation.One exception to this rule is if you are using durable functions. You are not billed for time spent at awaits in orchestrator functions.apply demand shaping techinques where possible (dev environments?) https://github.com/Azure-Samples/functions-csharp-premium-scaler", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "17bf6351-3e5e-41f1-87bb-d5ad0b4e3de6", - "link": "https://learn.microsoft.com/azure/frontdoor/routing-methods#23session-affinity", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "df03a822-cd46-43cb-abc8-ac299ebc91a4", + "link": "https://learn.microsoft.com/azure/sentinel/quickstart-onboard", "services": [ - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Decide if your application requires session affinity. If you have high reliability requirements, we recommend that you disable session affinity.", - "waf": "Reliability" + "subcategory": "Networking", + "text": "Evaluate your network topology against networking costs and where applicable reduce the egress and peering data", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "425bfb31-94c4-4007-b9ae-46da9fe57cc7", - "link": "https://learn.microsoft.com/azure/frontdoor/origin?pivots=front-door-standard-premium#origin-host-header", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "3da1dae2-cc88-4147-8607-c1cca0e61465", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "service": "Front Door", "services": [ - "FrontDoor" + "EventHubs", + "FrontDoor", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Send the host header to the back end. The back-end services should be aware of the host name so that they can create rules to accept traffic only from that host.", - "waf": "Security" + "subcategory": "Networking", + "text": "Frontdoor - Turn off the default homepageIn the application settings of your App, set AzureWebJobsDisableHomepage to true. This will return a 204 (No Content) to the PoP so only header data is returned.", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "81a5398a-2414-450f-9fc3-e048bc65784c", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-caching", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "8dd458e9-2713-49b8-8110-2dbd6eaf11e6", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", "service": "Front Door", "services": [ - "FrontDoor" + "AppSvc", + "FrontDoor", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use caching for endpoints that support it.", + "subcategory": "Networking", + "text": "Frontdoor - Route to something that returns nothing. Either set up a Function, Function Proxy, or add a route in your WebApp that returns 200 (OK) and sends no or minimal content. The advantage of this is you will be able to log out when it is called.", "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend healthprobe=tostring(properties.healthProbeSettings) | project origingroupname=name, id, tags, resourceGroup, subscriptionId, healthprobe, frontDoorId | join ( cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/Origins' | extend origingroupname = tostring(properties.originGroupName) ) on origingroupname | summarize origincount=count(), enabledhealthprobecount=countif(healthprobe != '') by origingroupname, id, tostring(tags), resourceGroup, subscriptionId, frontDoorId | extend compliant = origincount > 1 or (origincount == 1 and enabledhealthprobecount == 0) | project id = frontDoorId, compliant", - "guid": "34069d73-e4de-46c5-a36f-625f87575a56", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "f843e52f-4722-4d92-ac1b-1cd521e54a29", + "link": "https://learn.microsoft.com/azure/azure-monitor/agents/diagnostics-extension-overview", "services": [ - "FrontDoor" + "Cost" ], - "severity": "Low", - "subcategory": "Front Door", - "text": "Disable health checks in single back-end pools. If you have only one origin configured in your Azure Front Door origin group, these calls are unnecessary. This is only recommended if you can't have multiple origins in your endpoint.", + "severity": "Medium", + "subcategory": "PaaS", + "text": "Consider using free tiers where applicable for all non-production environments", "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "c92d6786-cdd1-444d-9cad-934a192a276a", - "link": "https://learn.microsoft.com/azure/frontdoor/standard-premium/how-to-reports", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "b9de39ac-0e7c-428d-a936-657202bff456", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", "services": [ - "Storage", - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "We recommend using the Premium Tier for leveraging the Security reports while the Standard Azure Front Door Profile provides only traffic reports under built-in analytics/reports.", - "waf": "Operations" + "subcategory": "Serverless", + "text": "Using serverless patterns for spikes can help keeping costs down", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "440cf7de-30a1-4550-ab50-c9f6eac140cd", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-wildcard-domain", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "7e31c67d-68cf-46a6-8a11-94956d697dc3", + "link": "https://learn.microsoft.com/azure/architecture/best-practices/monitoring", + "service": "Storage", "services": [ - "AKV", - "FrontDoor" + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use wildcard TLS certificates when possible.", - "waf": "Operations" + "subcategory": "Storage", + "text": "Consider archiving tiers for less used data", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "556e2733-6ca9-4edd-9cc7-26de66d46c2e", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-caching", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "a2ed27b2-d186-4f1a-8252-bddde68a487c", + "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", + "service": "VM", "services": [ - "FrontDoor" + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Optimize your application query string for caching. For purely static content, ignore query strings to maximize your use of the cache. If your application uses query strings, consider including them in the cache key. Including the query strings in the cache key allows Azure Front Door to serve cached responses or other responses, based on your configuration.", - "waf": "Performance" + "subcategory": "Storage", + "text": "Check disk sizes where the size does not match the tier (i.e. A 513 GiB disk will pay a P30 (1TiB) and consider resizing", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "c0b7e55e-fcab-4e66-bdae-bd0290f6aece", - "link": "https://learn.microsoft.com/azure/frontdoor/standard-premium/how-to-compression", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "dec4861b-c3bc-410a-b77e-26e4d5a3bec2", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", + "service": "Storage", "services": [ "Storage", - "FrontDoor" + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Use file compression when you're accessing downloadable content.", - "waf": "Performance" + "subcategory": "Storage", + "text": "Consider using standard SSD rather than Premium or Ultra where possible", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.network/frontdoors' and properties['resourceState'] !~ 'migrated' | extend compliant = false | project id, compliant", - "guid": "cb8eb8c0-aa73-4a26-a495-6eba8dc4a243", - "link": "https://learn.microsoft.com/azure/cdn/tier-migration", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "c4e2436b-1336-4db5-9f17-960eee0bdf5c", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", + "service": "Storage", "services": [ - "FrontDoor" + "Storage", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "Consider migrating to Standard or Premium SKU if you are using Classic Azure Front Door currently as Classic Azure Front Door will be deprecated by March 2027.", - "waf": "Operations" + "severity": "Medium", + "subcategory": "Storage", + "text": "For storage accounts, make sure that the chosen tier is not adding up transaction charges (it might be cheaper to move to the next tier)", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "67c33697-15b1-4752-aeee-0b9b588defc4", - "link": "https://learn.microsoft.com/azure/architecture/guide/networking/global-web-applications/mission-critical-content-delivery", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "c2efc5d7-61d4-41d2-900b-b47a393a040f", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", + "service": "Site Recovery", "services": [ "Storage", - "FrontDoor", - "TrafficManager" + "ASR", + "Cost" ], "severity": "Medium", - "subcategory": "Front Door", - "text": "Consider using Traffic Manager load balancing Azure Front Door and a third party CDN provider CDN profile for mission critical high availability scenario. ", - "waf": "Reliability" + "subcategory": "Storage", + "text": "For ASR, consider using Standard SSD disks if the RPO/RTO and replication throughput allow it", + "waf": "Cost" }, { - "category": "Network Topology and Connectivity", - "checklist": "Azure Application Delivery Networking", - "guid": "972cd4cd-25b0-4b70-96e9-eab4bfd32907", - "link": "https://learn.microsoft.com/azure/app-service/app-service-ip-restrictions?tabs=azurecli#restrict-access-to-a-specific-azure-front-door-instance", - "service": "Front Door", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "d3294798-b118-48b2-a5a4-6ceb544451e1", + "link": "https://learn.microsoft.com/azure/architecture/framework/resiliency/backup-and-recovery", + "service": "Storage", "services": [ - "AppSvc", - "FrontDoor" + "Storage", + "Cost" ], - "severity": "High", - "subcategory": "Front Door", - "text": "When using Front Door with origin as App services, consider locking down the traffic to app services only through Azure Front Door using access restrictions. ", - "waf": "Security" + "severity": "Medium", + "subcategory": "storage", + "text": "Storage accounts: check hot tier and/or GRS necessary", + "waf": "Cost" }, { - "category": "BCDR", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Ensure that your backups are protected against attacks. This should include encryption of the backups to protect against loss of confidentiality. For regular Azure service backup, backup data is automatically encrypted using Azure platform-managed keys. You can also choose to encrypt the backup using a customer-managed key. In this case, ensure this customer-managed key in the key vault is also in the backup scope.", - "guid": "676f6951-0368-49e9-808d-c33a692c9a64", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "92d34429-3c76-4286-97a5-51c5b04e4f18", + "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", + "service": "VM", "services": [ - "AKV", - "Backup", - "SQL" + "Storage", + "Cost" ], "severity": "Medium", - "subcategory": "Azure Key Vault", - "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", - "waf": "Security" + "subcategory": "Storage", + "text": "Disks - validate use of Premium SSD disks everywhere: for example, non-prod could swap to Standard SSD or on-demand Premium SSD ", + "waf": "Cost" }, { - "category": "BCDR", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database uses SQL Server technology to create full backups every week, differential backup every 12-24 hours, and transaction log backup every 5 to 10 minutes. By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region.", - "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "54387e5c-ed12-46cd-832a-f5b2fc6998a5", + "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", + "service": "Synapse", "services": [ - "Storage", - "Backup", - "SQL" + "Monitor", + "EventHubs", + "Cost" ], "severity": "Medium", - "subcategory": "Backup", - "text": "Configure Azure SQL Database automated backups", - "waf": "Security" + "subcategory": "Synapse", + "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks.", + "waf": "Cost" }, { - "category": "BCDR", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region. For SQL Database, the backup storage redundancy can be configured at the time of database creation or can be updated for an existing database; the changes made to an existing database apply to future backups only.", - "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", - "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "35e33789-7e31-4c67-b68c-f6a62a119495", + "link": "https://learn.microsoft.com/azure/virtual-machines/availability", + "service": "Synapse", "services": [ "Storage", - "Backup", - "SQL" + "Cost" ], - "severity": "Low", - "subcategory": "Backup", - "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", - "waf": "Security" + "severity": "Medium", + "subcategory": "Synapse", + "text": "Export cost data to a storage account for additional data analysis.", + "waf": "Cost" }, { - "category": "Code", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Malicious code can potentially circumvent security controls. Before deploying custom code to production, it is essential to review what's being deployed. Use a database tool like Azure Data Studio that supports source control. Implement tools and logic for code analysis, vulnerability and credential scanning.", - "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "6d697dc3-a2ed-427b-8d18-6f1a1252bddd", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "service": "Synapse", "services": [ - "SQL" + "SQL", + "Cost" ], "severity": "Medium", - "subcategory": "Source Control and Code Review", - "text": "Use Source Control systems to store, maintain and review application code deployed inside Azure SQLDB Database", - "waf": "Security" + "subcategory": "Synapse", + "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use.", + "waf": "Cost" }, { - "category": "Data Discovery and Classification", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "In case of classification requirements Purview is the preferred option. Only use SQL Data Discovery & Classification in case Purview is not an option. Discover columns that potentially contain sensitive data. What is considered sensitive data heavily depends on the customer, compliance regulation, etc., and needs to be evaluated by the users in charge of that data. Classify the columns to use advanced sensitivity-based auditing and protection scenarios. Review results of automated discovery and finalize the classification if necessary.", - "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", - "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "e68a487c-dec4-4861-ac3b-c10ae77e26e4", + "link": "https://learn.microsoft.com/azure/virtual-machine-scale-sets/overview", + "service": "Synapse", "services": [ - "SQL" + "Cost" ], - "severity": "Low", - "subcategory": "Data Discovery and Classification", - "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", - "waf": "Security" + "severity": "Medium", + "subcategory": "Synapse", + "text": "Enable the serverless Apache Spark automatic pause feature and set your timeout value accordingly.", + "waf": "Cost" }, { - "category": "Data Masking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Usage of this feature is recommended only if column encryption is not an option and there is a specific requirement to preserve data types and formats. Dynamic data masking limits sensitive data exposure by masking it to non-privileged users. Dynamic data masking helps prevent unauthorized access to sensitive data by enabling customers to designate how much of the sensitive data to reveal with minimal impact on the application layer.", - "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", - "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "d5a3bec2-c4e2-4436-a133-6db55f17960e", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "service": "Synapse", "services": [ - "SQL" + "Cost" ], - "severity": "Low", - "subcategory": "Data Masking", - "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible", - "waf": "Security" + "severity": "Medium", + "subcategory": "Synapse", + "text": "Create multiple Apache Spark pool definitions of various sizes.", + "waf": "Cost" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "SQL Advanced Threat Detection (ATP) provides a layer of security that detects potential vulnerabilities and anomalous activity in databases such as SQL injection attacks and unusual behavior patterns. When a potential threat is detected Threat Detection sends an actionable real-time alert by email and in Microsoft Defender for Cloud, which includes clear investigation and remediation steps for the specific threat.", - "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "ee0bdf5c-c2ef-4c5d-961d-41d2500bb47a", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", + "service": "Synapse", "services": [ - "Defender", - "EventHubs", - "SQL" + "Cost" ], - "severity": "High", - "subcategory": "Advanced Threat Protection", - "text": "Review and complete Advanced Threat Protection (ATP) configuration", - "waf": "Security" + "severity": "Medium", + "subcategory": "Synapse", + "text": "Purchase Azure Synapse commit units (SCU) for one year with a pre-purchase plan to save on your Azure Synapse Analytics costs.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Cost" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Enable Microsoft Defender for Azure SQL at the subscription level to automatically onboard and protect all existing and future servers and databases. When you enable on the subscription level, all databases in Azure SQL Database and Azure SQL Managed Instance are protected. You can then disable them individually if you choose. If you want to manually manage which databases are protected, disable at the subscription level and enable each database that you want protected.", - "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", - "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "393a040f-d329-4479-ab11-88b2c5a46ceb", + "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "service": "VM", "services": [ - "Defender", - "SQL", - "Subscriptions" + "VM", + "Cost" ], - "severity": "High", - "subcategory": "Defender for Azure SQL", - "text": "Enable Microsoft Defender for Azure SQL", - "waf": "Security" + "severity": "Medium", + "subcategory": "VM", + "text": "Use Spot VMs for interruptible jobs: These are VMs that can be bid on and purchased at a discounted price, providing a cost-effective solution for non-critical workloads.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Cost" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Microsoft Defender for Azure SQL ATP detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. Alerts can be configured and generated and will be reported in the Defender for console.", - "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "544451e1-92d3-4442-a3c7-628637a551c5", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "service": "VM", "services": [ - "Defender", - "Monitor", - "SQL" + "VM", + "Cost" ], - "severity": "High", - "subcategory": "Defender for Azure SQL", - "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", - "waf": "Security" + "severity": "Medium", + "subcategory": "VM", + "text": "Right-sizing all VMs", + "waf": "Cost" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQLDB vulnerability assessment is a service that provides visibility into your security state. Vulnerability assessment includes actionable steps to resolve security issues and enhance your database security. It can help you to monitor a dynamic database environment where changes are difficult to track and improve your SQL security posture.", - "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "b04e4f18-5438-47e5-aed1-26cd032af5b2", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", + "service": "VM", "services": [ - "Defender", - "Monitor", - "SQL" + "VM", + "Cost" ], - "severity": "High", - "subcategory": "Vulnerability Assessment", - "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", - "waf": "Security" + "severity": "Medium", + "subcategory": "VM", + "text": "Swap VM sized with normalized and most recent sizes", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Cost" }, { - "category": "Defender", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Microsoft Defender for Cloud provides vulnerability assessment for your Azure SQL Databases. Vulnerability assessment scans your databases for software vulnerabilities and provides a list of findings. You can use the findings to remediate software vulnerabilities and disable findings.", - "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "fc6998a5-35e3-4378-a7e3-1c67d68cf6a6", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "VM", "services": [ - "Defender", - "SQL" + "Monitor", + "VM", + "Cost" ], - "severity": "High", - "subcategory": "Vulnerability Assessment", - "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", - "waf": "Security" + "severity": "Medium", + "subcategory": "VM", + "text": "right-sizing VMs - start with monitoring usage below 5% and then work up to 40%", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Cost" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Always Encrypted with Secure Enclaves expands confidential computing capabilities of Always Encrypted by enabling in-place encryption and richer confidential queries. Always Encrypted with Secure Enclaves addresses these limitations by allowing some computations on plaintext data inside a secure enclave on the server side. Usage of this feature is recommended for the cases where you need to limit administrator access and need your queries to support more than equality matching of encrypted columns.", - "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", - "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", + "category": "Right-sizing", + "checklist": "Cost Optimization Checklist", + "guid": "2a119495-6d69-47dc-9a2e-d27b2d186f1a", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "VM", "services": [ - "SQL" + "VM", + "Cost" ], "severity": "Medium", - "subcategory": "Always Encrypted", - "text": "If protecting sensitive PII data from admin users is a key requirement, but Column Encryption limitations cannot be tolerated, consider the adoption of Always Encrypted with Secure Enclaves", - "waf": "Security" + "subcategory": "VM", + "text": "Containerizing an application can improve VM density and save money on scaling it", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Cost" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "With Azure SQL Database, you can apply symmetric encryption to a column of data by using Transact-SQL. This approach is called column encryption, because you can use it to encrypt specific columns with different encryption keys. Doing so gives you more granular encryption capability than TDE, which encrypts data in pages. Using Always Encrypted to ensure sensitive data isn't exposed in plaintext in Azure SQL Database or SQL Managed Instance, even in memory/in use. Always Encrypted protects the data from Database Administrators (DBAs) and cloud admins (or bad actors who can impersonate high-privileged but unauthorized users) and gives you more control over who can access your data.", - "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.Cdn/profiles/secrets' | extend frontDoorId = substring(id, 0, indexof(id, '/secrets')) | where properties.parameters.type =~ 'CustomerCertificate' | extend compliant = properties.parameters.useLatestVersion == true | project compliant, id=frontDoorId, certificateName = name | distinct id, certificateName, compliant", + "guid": "f00a69de-7076-4734-a734-6e4552cad9e1", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-latest-version-for-customer-managed-certificates", + "service": "Front Door", "services": [ - "Storage", "AKV", - "SQL" + "FrontDoor" ], - "severity": "Low", - "subcategory": "Column Encryption", - "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption", - "waf": "Security" + "severity": "Medium", + "subcategory": "Front Door", + "text": "If you use customer-managed TLS certificates with Azure Front Door, use the 'Latest' certificate version. Reduce the risk of outages caused by manual certificate renewal.", + "waf": "Operations" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Enabled by default, Transparent data encryption (TDE) helps to protect the database files against information disclosure by performing real-time encryption and decryption of the database, associated backups, and transaction log files 'at rest', without requiring changes to the application.", - "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.cdn/profiles' and sku has 'AzureFrontDoor' | project name, cdnprofileid=tolower(id), tostring(tags), resourceGroup, subscriptionId,skuname=tostring(sku.name) | join kind= fullouter ( cdnresources | where type == 'microsoft.cdn/profiles/securitypolicies' | extend wafpolicyid=tostring(properties['parameters']['wafPolicy']['id']) | extend splitid=split(id, '/') | extend cdnprofileid=tolower(strcat_array(array_slice(splitid, 0, 8), '/')) | project secpolname=name, cdnprofileid, wafpolicyid ) on cdnprofileid | project name, cdnprofileid, secpolname, wafpolicyid,skuname | join kind = fullouter ( resources | where type == 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | extend managedrulesenabled=iff(tostring(properties.managedRules.managedRuleSets) != '[]', true, false), enabledState = tostring(properties.policySettings.enabledState) | project afdwafname=name, managedrulesenabled, wafpolicyid=id, enabledState, tostring(tags) ) on wafpolicyid | where name != '' | summarize associatedsecuritypolicies=countif(secpolname != ''), wafswithmanagedrules=countif(managedrulesenabled == 1) by name, id=cdnprofileid, tags,skuname | extend compliant = (associatedsecuritypolicies > 0 and wafswithmanagedrules > 0) | project id, compliant", + "guid": "e79d17b7-3b22-4a5a-97e7-a8ed4b30e38c", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "Front Door", "services": [ - "Storage", - "Backup", - "SQL" + "AzurePolicy", + "FrontDoor", + "WAF" ], - "severity": "High", - "subcategory": "Transparent Data Encryption", - "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", + "severity": "Medium", + "subcategory": "Front Door", + "text": "Use Azure Front Door with WAF policies to deliver and help protect global HTTP/S apps that span multiple Azure regions.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "If separation of duties in the management of keys and data within the organization is required, leverage Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) for your Azure SQLDB and use Azure Key Vault to store (refer to its checklist). Leverage this feature when you have strict security requirements which cannot be met by the managed service keys.", - "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "link": "https://learn.microsoft.com/azure/frontdoor/origin-security?tabs=application-gateway&pivots=front-door-standard-premium#example-configuration", + "service": "Front Door", "services": [ - "AKV", - "SQL" + "AzurePolicy", + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Medium", - "subcategory": "Transparent Data Encryption", - "text": "Use customer-managed keys (CMK) in Azure Key Vault (AKV) if you need increased transparency and granular control over the TDE protection", + "subcategory": "Front Door", + "text": "When using Front Door and Application Gateway to help protect HTTP/S apps, use WAF policies in Front Door. Lock down Application Gateway to receive traffic only from Front Door.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Security" }, { - "category": "Encryption", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The minimal Transport Layer Security (TLS) version setting allows customers to choose which version of TLS their SQL database uses. It's possible to change the minimum TLS version by using the Azure portal, Azure PowerShell, and the Azure CLI.", - "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | project policyName=name, policyId=id,policySku=sku.name, links=properties.securityPolicyLinks, enabledState=properties.policySettings.enabledState, mode=properties.policySettings.mode | mvexpand links | extend securityPolicy=links.id | extend securityPolicyParts=split(securityPolicy, '/') | extend profileId=strcat_array(array_slice(securityPolicyParts, 0, -3), '/') | project id=profileId, compliant=((enabledState=='Enabled') and (mode=='Prevention')), enabledState, mode", + "guid": "ae248989-b306-4591-9186-de482e3f0f0e", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "service": "Front Door", "services": [ - "SQL" + "AzurePolicy", + "FrontDoor", + "WAF" ], "severity": "High", - "subcategory": "Transport Layer Security", - "text": "Enforce minimum TLS version to the latest available", + "subcategory": "Front Door", + "text": "Deploy your WAF policy for Front Door in 'Prevention' mode' so that Web Application Firewall takes appropriate action to allow or deny traffic.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Use Azure Active Directory (Azure AD) authentication for centralized identity management. Use SQL Authentication only if really necessary and document as exceptions.", - "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/origins' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend compliant = properties['hostName'] !endswith '.trafficmanager.net' | project compliant, id=frontDoorId", + "guid": "062d5839-4d36-402f-bfa4-02811eb936e9", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "service": "Front Door", "services": [ - "Entra", - "SQL" + "EventHubs", + "TrafficManager", + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", + "severity": "High", + "subcategory": "Front Door", + "text": "Avoid placing Traffic Manager behind Front Door.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Using Azure AD groups simplifies permission management and both the group owner, and the resource owner can add/remove members to/from the group. Create a separate group for Azure AD administrators for each logical server. Monitor Azure AD group membership changes using Azure AD audit activity reports.", - "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/origins' | extend frontDoorId = substring(id, 0, indexof(id, '/origins')) | extend compliant = isempty(properties.originHostHeader) or (tostring(properties.hostName) =~ tostring(properties.originHostHeader)) | project id=frontDoorId, originName = name, compliant", + "guid": "5efeb96a-003f-4b18-8fcd-b4d84459c2b2", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "service": "Front Door", "services": [ - "Monitor", - "Entra", - "SQL" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server", + "severity": "High", + "subcategory": "Front Door", + "text": "Use the same domain name on Azure Front Door and your origin. Mismatched host names can cause subtle bugs.", "waf": "Security" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Ensure that distinct system and user assigned managed identities, that are dedicated to the function, with least permissions assigned, are used for communication from Azure services and applications to the Azure SQLDB databases.", - "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/origins' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend originGroupId = substring(id, 0, indexof(id, '/origins')) | join kind=inner (cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend originGroupName = name | extend hasHealthProbe = isnotnull(properties.healthProbeSettings)) on $left.originGroupId == $right.id | summarize numberOrigins = count() by originGroupId, subscriptionId, frontDoorId, hasHealthProbe, originGroupName | extend compliant = not(numberOrigins == 1 and hasHealthProbe) | project id = frontDoorId, compliant", + "guid": "0b5a380c-4bfb-47bc-b1d7-dcfef363a61b", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "service": "Front Door", "services": [ - "Entra", - "SQL" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Azure Active Directory", - "text": "Minimize the use of password-based authentication for applications", - "waf": "Security" + "severity": "Low", + "subcategory": "Front Door", + "text": "Disable health probes when there is only one origin in an Azure Front Door origin group.", + "waf": "Performance" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "System or User assigned managed identities enable Azure SQLDB to authenticate to other cloud services (e.g. Azure Key Vault) without storing credentials in code. Once enabled, all necessary permissions can be granted via Azure role-based-access-control to the specific Azure SQLDB instance. Do not share user assigned managed identities across multiple services if not strictly required.", - "guid": "69891194-5074-4e30-8f69-4efc3c580900", - "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "5567048e-e5d7-4206-9c55-b5ed45d2cc0c", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "service": "Front Door", "services": [ - "ACR", - "AKV", - "RBAC", - "SQL", - "Entra" + "FrontDoor" ], - "severity": "Low", - "subcategory": "Managed Identities", - "text": "Assign Azure SQL Database a managed identity for outbound resource access", - "waf": "Security" + "severity": "Medium", + "subcategory": "Front Door", + "text": "Select good health probe endpoints for Azure Front Door. Consider building health endpoints that check all of your application's dependencies.", + "waf": "Reliability" }, { - "category": "Identity", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Use an Azure AD integrated authentication that eliminates the use of passwords. Password-based authentication methods are a weaker form of authentication. Credentials can be compromised or mistakenly given away. Use single sign-on authentication using Windows credentials. Federate the on-premises AD domain with Azure AD and use integrated Windows authentication (for domain-joined machines with Azure AD).", - "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups/')) | extend compliant = (isnull(properties['healthProbeSettings']['probeRequestType']) or toupper(properties['healthProbeSettings']['probeRequestType']) == 'HEAD') | project compliant, id=frontDoorId", + "guid": "a13f72f3-8f5c-4864-95e5-75bf37fbbeb1", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "service": "Front Door", "services": [ - "Entra", - "SQL" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Passwords", - "text": "Minimize the use of password-based authentication for users", - "waf": "Security" + "severity": "Low", + "subcategory": "Front Door", + "text": "Use HEAD health probes with Azure Front Door, to reduce the traffic that Front Door sends to your application.", + "waf": "Performance" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Confidential Ledger is one of the supported store, it can be used and supports automatic generation and storage of database digests. Azure Ledger provides advanced security features like Blockchain Ledger Proof and Confidential Hardware Enclaves. Use it only if advanced security features are required, otherwise revert to Azure storage.", - "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", - "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/customdomains' | extend frontDoorId = substring(id, 0, indexof(id, '/customdomains')) | extend compliant = (isnull(properties['tlsSettings']['certificateType']) or tolower(properties['tlsSettings']['certificateType']) =~ 'customercertificate') | project compliant, id = frontDoorId", + "guid": "af95c92d-d723-4f4a-98d7-8722324efd4d", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "service": "Front Door", "services": [ - "Storage", - "SQL" + "AKV", + "FrontDoor", + "Cost" ], - "severity": "Medium", - "subcategory": "Database Digest", - "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", - "waf": "Security" + "severity": "High", + "subcategory": "Front Door", + "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", + "waf": "Operations" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Blob Storage with Immutable Storage feature can be used and supports automatic generation and storage of database digests. To prevent tampering of your digest files, configure and lock a retention policy for your container.", - "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "189ea962-3969-4863-8f5a-5ad808c2cf4b", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#define-your-waf-configuration-as-code", + "service": "Front Door", "services": [ - "AzurePolicy", - "Storage", - "SQL" + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "Database Digest", - "text": "If Azure storage account is used to store database digests, ensure security is properly configured", - "waf": "Security" + "subcategory": "Front Door", + "text": "Define your Azure Front Door WAF configuration as code. By using code, you can more easily adopt new rule set version and gain additional protection.", + "waf": "Operations" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Ledger provides a form of data integrity called forward integrity, which provides evidence of data tampering on data in your ledger tables. The database verification process takes as input one or more previously generated database digests. It then recomputes the hashes stored in the database ledger based on the current state of the ledger tables. If the computed hashes don't match the input digests, the verification fails. The failure indicates that the data has been tampered with. The verification process reports all inconsistencies that it detects.", - "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type == 'microsoft.cdn/profiles/afdendpoints/routes' | extend frontDoorId = substring(id, 0, indexof(id, '/afdendpoints')) | extend forwardingProtocol=tostring(properties.forwardingProtocol),supportedProtocols=properties.supportedProtocols,httpsRedirect=properties.httpsRedirect | extend compliant = forwardingProtocol =~ 'httpsonly' and (supportedProtocols has 'https' or httpsRedirect =~ 'enabled') | project id = frontDoorId, compliant", + "guid": "2e30abab-5478-417c-81bf-bf1ad4ed1ed4", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-end-to-end-tls", + "service": "Front Door", "services": [ - "Storage", - "SQL" + "FrontDoor" ], - "severity": "Medium", - "subcategory": "Integrity", - "text": "Schedule the Ledger verification process regularly to verify data integrity", + "severity": "High", + "subcategory": "Front Door", + "text": "Use end-to-end TLS with Azure Front Door. Use TLS for connections from your clients to Front Door, and from Front Door to your origin.", "waf": "Security" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The Ledger feature provides tamper-evidence capabilities in your database. You can cryptographically attest to other parties, such as auditors or other business parties, that your data hasn't been tampered with. Ledger helps protect data from any attacker or high-privileged user, including database administrators (DBAs), system administrators, and cloud administrators.", - "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type == 'microsoft.cdn/profiles/afdendpoints/routes' | extend frontDoorId = substring(id, 0, indexof(id, '/afdendpoints')) | extend forwardingProtocol=tostring(properties.forwardingProtocol),supportedProtocols=properties.supportedProtocols,httpsRedirect=properties.httpsRedirect | extend compliant = httpsRedirect =~ 'enabled' | project id = frontDoorId, compliant", + "guid": "10aa45af-166f-44c4-9f36-b6d592dac2ca", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-http-to-https-redirection", + "service": "Front Door", "services": [ - "SQL" + "FrontDoor" ], "severity": "Medium", - "subcategory": "Ledger", - "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", + "subcategory": "Front Door", + "text": "Use HTTP to HTTPS redirection with Azure Front Door. Support older clients by redirecting them to an HTTPS request automatically.", "waf": "Security" }, { - "category": "Ledger", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Depending on the type of tampering, there are cases where you can repair the ledger without losing data. In the article contained in the --More Info-- column, different scenarios and recovery techniques are described.", - "guid": "804fc554-6554-4842-91c1-713b32f99902", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.network/frontdoorwebapplicationfirewallpolicies' | project policyName=name, policyId=id,policySku=sku.name, links=properties.securityPolicyLinks, enabledState=properties.policySettings.enabledState, mode=properties.policySettings.mode | mvexpand links | extend securityPolicy=links.id | extend securityPolicyParts=split(securityPolicy, '/') | extend profileId=strcat_array(array_slice(securityPolicyParts, 0, -3), '/') | project id=profileId, compliant=((enabledState=~'Enabled') and (mode=~'Prevention')), enabledState, mode", + "guid": "28b9ee82-b2c7-45aa-bc98-6de6f59a095d", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#enable-the-waf", + "service": "Front Door", "services": [ - "SQL" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "subcategory": "Recovery", - "text": "Prepare a response plan to investigate and repair a database after a tampering event", + "severity": "High", + "subcategory": "Front Door", + "text": "Enable the Azure Front Door WAF. Protect your application from a range of attacks.", "waf": "Security" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database Auditing tracks database events and writes them to an audit log in your Azure storage account. Auditing helps you understand database activity and gain insight into discrepancies and anomalies that could indicate business concerns or suspected security violations as well as helps you meet regulatory compliance. By default auditing policy includes all actions (queries, stored procedures and successful and failed logins) against the databases, which may result in high volume of audit logs. It's recommended for customers to configure auditing for different types of actions and action groups using PowerShell.", - "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "2902d8cc-1b0c-4495-afad-624ab70f7bd6", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#tune-your-waf", + "service": "Front Door", "services": [ - "AzurePolicy", - "Storage", - "SQL" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", + "severity": "High", + "subcategory": "Front Door", + "text": "Tune the Azure Front Door WAF for your workload by configuring the WAF in Detection mode to reduce and fix false positive detections.", "waf": "Security" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database Auditing logs can be written to external storage accounts, Log Analytics workspace or Event Hub. Be sure to protect the target repository using backups and secured configuration. Use Azure SQL Database Managed Identity to access the storage and set an explicit retention period. Do not grant permissions to administrators to the audit log repository. Use a different target storage for --Enabling Auditing of Microsoft support operations--. ", - "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "17ba124b-127d-42b6-9322-388d5b2bbcfc", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", + "service": "Front Door", "services": [ - "Monitor", - "EventHubs", - "Backup", - "Storage", - "SQL", - "Entra" + "AzurePolicy", + "FrontDoor", + "WAF" ], - "severity": "Low", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", + "severity": "High", + "subcategory": "Front Door", + "text": "Enable request body inspection feature enabled in Azure Front Door WAF policy.", "waf": "Security" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The Azure Monitor activity log is a platform log in Azure that provides insight into subscription-level events. The activity log includes information like when a resource is modified. It is recommended to send this activity log to the same external storage repository as the Azure SQL Database Audit Log (storage account, Log Analytics workspace, Event Hub).", - "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "49a98f2b-ec22-4a87-9415-6a10b00d6555", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-default-rule-sets", + "service": "Front Door", "services": [ - "Monitor", - "EventHubs", - "Storage", - "SQL", - "Subscriptions" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", + "severity": "High", + "subcategory": "Front Door", + "text": "Enable the Azure Front Door WAF default rule sets. The default rule sets detect and block common attacks.", "waf": "Security" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR). Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", - "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "147a13d4-2a2f-4824-a524-f5855b52b946", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#enable-bot-management-rules", + "service": "Front Door", "services": [ - "Monitor", - "SQL" + "FrontDoor", + "WAF" ], - "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", + "severity": "High", + "subcategory": "Front Door", + "text": "Enable the Azure Front Door WAF bot protection rule set. The bot rules detect good and bad bots.", "waf": "Security" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR), which can be used to set up custom threat detections. Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", - "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "d7dcdcb9-0d99-44b9-baab-ac7570ede79a", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-the-latest-ruleset-versions", + "service": "Front Door", "services": [ - "Monitor", - "SQL" + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", + "subcategory": "Front Door", + "text": "Use the latest Azure Front Door WAF rule set version. Rule set updates are regularly updated to take account of the current threat landscape.", "waf": "Security" }, { - "category": "Logging", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Security Operation Center (SOC) team should create an incident response plan (playbooks or manual responses) to investigate and mitigate tampering, malicious activities, and other anomalous behaviors.", - "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "b9620385-1cde-418f-914b-a84a06982ffc", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-rate-limiting", + "service": "Front Door", "services": [ - "EventHubs", - "SQL" + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "SIEM/SOAR", - "text": "Ensure that you have response plans for malicious or aberrant audit logging events", + "subcategory": "Front Door", + "text": "Add rate limiting to the Azure Front Door WAF. Rate limiting blocks clients accidentally or intentionally sending large amounts of traffic in a short period of time.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "When you create a logical server from the Azure portal for Azure SQL Database, the result is a public endpoint that is visible and reachable over the public network (Public Access). You can then limit connectivity based on firewall rules and Service Endpoint. You can also configure private connectivity only limiting connections to internal networks using Private Endpoint (Private Access). Private Access using Private Endpoint should be the default unless a business case or performance/technical reason applies that cannot support it. Usage of Private Endpoints has performance implications that need to be considered and assessed.", - "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "6dc36c52-0124-4ffe-9eaf-23ec1282dedb", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#use-a-high-threshold-for-rate-limits", + "service": "Front Door", "services": [ - "PrivateLink", - "SQL" + "FrontDoor", + "WAF" ], - "severity": "High", - "subcategory": "Connectivity", - "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", + "severity": "Medium", + "subcategory": "Front Door", + "text": "Use a high threshold for Azure Front Door WAF rate limits. High rate limit thresholds avoid blocking legitimate traffic, while still providing protection against extremely high numbers of requests that might overwhelm your infrastructure.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "IMPORTANT: Connections to private endpoint only support Proxy as the connection policy. When using private endpoints connections are proxied via the Azure SQL Database gateway to the database nodes. Clients will not have a direct connection.", - "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "388a3d0e-0a43-4367-90b2-3dd2aeece5ee", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#geo-filter-traffic", + "service": "Front Door", "services": [ - "AzurePolicy", - "PrivateLink", - "SQL" + "FrontDoor" ], "severity": "Low", - "subcategory": "Connectivity", - "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", + "subcategory": "Front Door", + "text": "If you are not expecting traffic from all geographical regions, use geo-filters to block traffic from non-expected countries.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers. If you select this option, make sure that your login and user permissions limit access to authorized users only. If not strictly required, keep this setting to OFF.", - "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "00acd8a9-6975-414f-8491-2be6309893b8", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#specify-the-unknown-zz-location", + "service": "Front Door", "services": [ - "SQL", - "Subscriptions" + "FrontDoor", + "WAF" ], - "severity": "High", - "subcategory": "Connectivity", - "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", + "severity": "Medium", + "subcategory": "Front Door", + "text": "Specify the unknown (ZZ) location when geo-filtering traffic with the Azure Front Door WAF. Avoid accidentally blocking legitimate requests when IP addresses can't be geo-matched.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure SQL Database has a new built-in feature that allows native integration with external REST endpoints. This means that integration of Azure SQL Database with Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management and in general any REST or even GraphQL endpoint. If not properly restricted, code inside an Azure SQL Database database could leverage this mechanism to exfiltrate data. If not strictly required, it is recommended to block or restrict this feature using Outbound Firewall Rules.", - "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", - "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "4cea4050-7946-4a7c-89e6-b021b73c352d", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", + "service": "Front Door", "services": [ - "EventHubs", - "SQL", - "APIM" + "Monitor", + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "Outbound Control", - "text": "Block or restrict outbound REST API calls to external endpoints", - "waf": "Security" + "subcategory": "Front Door", + "text": "Capture logs and metrics by turning on Diagnostic Settings. Include resource activity logs, access logs, health probe logs, and WAF logs. Set up alerts.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Outbound firewall rules limit network traffic from the Azure SQL Database logical server to a customer defined list of Azure Storage accounts and Azure SQL Database logical servers. Any attempt to access storage accounts or databases not in this list is denied.", - "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", - "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "845f5f91-9c21-4674-a725-5ce890850e20", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", + "service": "Front Door", "services": [ - "Storage", - "SQL" + "Sentinel", + "FrontDoor", + "WAF" ], "severity": "Medium", - "subcategory": "Outbound Control", - "text": "If outbound network access is required, it is recommended to configure outbound networking restrictions using built-in Azure SQL Database control feature", - "waf": "Security" + "subcategory": "Front Door", + "text": "Send Azure Front Door WAF logs to Microsoft Sentinel.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Private Endpoint is created inside a subnet in an Azure Virtual Network. Proper security configuration must be applied also to the containing network environment, including NSG/ASG, UDR, firewall, monitoring and auditing.", - "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "3bb0a854-ea3d-4212-bd8e-3f0cb7792b02", + "link": "https://learn.microsoft.com/azure/frontdoor/routing-methods", + "service": "Front Door", "services": [ - "Monitor", - "Firewall", - "SQL", - "VNet", - "PrivateLink" + "Backup", + "FrontDoor" ], "severity": "Medium", - "subcategory": "Private Access", - "text": "If Private Access connectivity is used, ensure that you are using the Private Endpoint, Azure Virtual Network, Azure Firewall, and Azure Network Security Group checklists", - "waf": "Security" + "subcategory": "Front Door", + "text": "Choose a routing method that supports your deployment strategy. The weighted method, which distributes traffic based on the configured weight coefficient, supports active-active models. A priority-based value that configures the primary region to receive all traffic and send traffic to the secondary region as a backup supports active-passive models. Combine the preceding methods with latency so that the origin with the lowest latency receives traffic.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "When adding a Private Endpoint connection, public routing to your logical server isn't blocked by default. In the --Firewall and virtual networks-- pane, the setting --Deny public network access-- is not selected by default. To disable public network access, ensure that you select --Deny public network access--.", - "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend healthprobe=tostring(properties.healthProbeSettings) | project origingroupname=name, id, tags, resourceGroup, subscriptionId, healthprobe, frontDoorId | join ( cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/Origins' | extend origingroupname = tostring(properties.originGroupName) ) on origingroupname | summarize origincount=count(), enabledhealthprobecount=countif(healthprobe != '') by origingroupname, id, tostring(tags), resourceGroup, subscriptionId, frontDoorId | extend compliant = origincount > 1 | project id = frontDoorId, compliant", + "guid": "c3a769e4-cc78-40a9-b36a-f9bcab19ec2d", + "link": "https://learn.microsoft.com/azure/frontdoor/quickstart-create-front-door", + "service": "Front Door", "services": [ - "PrivateLink", - "SQL", - "VNet" + "FrontDoor" ], "severity": "High", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", - "waf": "Security" + "subcategory": "Front Door", + "text": "Support redundancy by having multiple origins in one or more back-end pools. Always have redundant instances of your application and make sure each instance exposes an endpoint or origin. You can place those origins in one or more back-end pools.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Network Security Group (NSG) and Application Security Group (ASG) can be now applied to subnet containing Private Endpoints to restrict connections to Azure SQLDB based on internal source IP ranges.", - "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", - "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "999852be-2137-4179-8fc3-30d1df6fed1d", + "link": "https://learn.microsoft.com/azure/frontdoor/troubleshoot-issues#troubleshooting-steps", + "service": "Front Door", "services": [ - "PrivateLink", - "SQL", - "VNet" + "FrontDoor" ], "severity": "Medium", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, apply NSG and eventually ASG to limit incoming source IP address ranges", - "waf": "Security" + "subcategory": "Front Door", + "text": "Set a timeout on forwarding requests to the back end. Adjust the timeout setting according to your endpoints' needs. If you don't, Azure Front Door might close the connection before the origin sends the response. You can also lower the default timeout for Azure Front Door if all of your origins have a shorter timeout.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. Applications and tools that are in the same or peered virtual network in the same region could access it directly. Applications and tools that are in different region could use virtual-network-to-virtual-network connection or ExpressRoute circuit peering to establish connection. Customer should use Network Security Groups (NSG), and eventually internal firewalls, to restrict access over port 1433 only to resources that require access to a managed instance.", - "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "17bf6351-3e5e-41f1-87bb-d5ad0b4e3de6", + "link": "https://learn.microsoft.com/azure/frontdoor/routing-methods#23session-affinity", + "service": "Front Door", "services": [ - "ExpressRoute", - "SQL", - "VNet" + "FrontDoor" ], "severity": "Medium", - "subcategory": "Private Access", - "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet", - "waf": "Security" + "subcategory": "Front Door", + "text": "Decide if your application requires session affinity. If you have high reliability requirements, we recommend that you disable session affinity.", + "waf": "Reliability" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Azure Virtual Network Service Endpoint is preferred solution if you want to establish a direct connection to the Azure SQL Database backend nodes using Redirect policy. This will allow access in high performance mode and is the recommended approach from a performance perspective.", - "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "425bfb31-94c4-4007-b9ae-46da9fe57cc7", + "link": "https://learn.microsoft.com/azure/frontdoor/origin?pivots=front-door-standard-premium#origin-host-header", + "service": "Front Door", "services": [ - "AzurePolicy", - "SQL", - "VNet" + "FrontDoor" ], - "severity": "High", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", + "severity": "Medium", + "subcategory": "Front Door", + "text": "Send the host header to the back end. The back-end services should be aware of the host name so that they can create rules to accept traffic only from that host.", "waf": "Security" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The Azure SQL Database firewall allows you to specify IP address ranges from which communications are accepted. This approach is fine for stable IP addresses that are outside the Azure private network.", - "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "81a5398a-2414-450f-9fc3-e048bc65784c", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-caching", + "service": "Front Door", "services": [ - "Storage", - "SQL" + "FrontDoor" ], "severity": "Medium", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", - "waf": "Security" + "subcategory": "Front Door", + "text": "Use caching for endpoints that support it.", + "waf": "Cost" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "We recommend that you use database-level IP firewall rules whenever possible. This practice enhances security and makes your database more portable. Use server-level IP firewall rules for administrators. Also use them when you have many databases that have the same access requirements, and you don't want to configure each database individually.", - "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", - "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups' | extend frontDoorId = substring(id, 0, indexof(id, '/origingroups')) | extend healthprobe=tostring(properties.healthProbeSettings) | project origingroupname=name, id, tags, resourceGroup, subscriptionId, healthprobe, frontDoorId | join ( cdnresources | where type =~ 'microsoft.cdn/profiles/origingroups/Origins' | extend origingroupname = tostring(properties.originGroupName) ) on origingroupname | summarize origincount=count(), enabledhealthprobecount=countif(healthprobe != '') by origingroupname, id, tostring(tags), resourceGroup, subscriptionId, frontDoorId | extend compliant = origincount > 1 or (origincount == 1 and enabledhealthprobecount == 0) | project id = frontDoorId, compliant", + "guid": "34069d73-e4de-46c5-a36f-625f87575a56", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "service": "Front Door", "services": [ - "Storage", - "SQL" + "FrontDoor" ], "severity": "Low", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used and controlled by Azure SQL Database firewall rules, use database-level over server-level IP rules", - "waf": "Security" + "subcategory": "Front Door", + "text": "Disable health checks in single back-end pools. If you have only one origin configured in your Azure Front Door origin group, these calls are unnecessary. This is only recommended if you can't have multiple origins in your endpoint.", + "waf": "Cost" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. The Managed Instance public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. If company policy disallows the use of public endpoints, use Azure Policy to prevent enabling public endpoints in the first place.", - "guid": "b8435656-143e-41a8-9922-61d34edb751a", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "c92d6786-cdd1-444d-9cad-934a192a276a", + "link": "https://learn.microsoft.com/azure/frontdoor/standard-premium/how-to-reports", + "service": "Front Door", "services": [ - "AzurePolicy", - "SQL", - "VNet" + "Storage", + "FrontDoor" ], - "severity": "High", - "subcategory": "Public Access", - "text": "Do not enable Azure SQL Managed Instance public endpoint", - "waf": "Security" + "severity": "Medium", + "subcategory": "Front Door", + "text": "We recommend using the Premium Tier for leveraging the Security reports while the Standard Azure Front Door Profile provides only traffic reports under built-in analytics/reports.", + "waf": "Operations" }, { - "category": "Networking", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "A Managed Instance (SQL MI) public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. In this case, it is recommended to apply a Network Security Groups (NSG) to restrict access to port 3342 only to trusted source IP addresses.", - "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "440cf7de-30a1-4550-ab50-c9f6eac140cd", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-wildcard-domain", + "service": "Front Door", "services": [ - "SQL", - "VNet" + "AKV", + "FrontDoor" ], - "severity": "High", - "subcategory": "Public Access", - "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", - "waf": "Security" + "severity": "Medium", + "subcategory": "Front Door", + "text": "Use wildcard TLS certificates when possible.", + "waf": "Operations" }, { - "category": "Privileged Access", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Most operations, support, and troubleshooting performed by Microsoft personnel and sub-processors do not require access to customer data. In those rare circumstances where such access is required, Customer Lockbox for Microsoft Azure provides an interface for customers to review and approve or reject customer data access requests. In support scenarios where Microsoft needs to access customer data, Azure SQL Database supports Customer Lockbox to provide an interface for you to review and approve or reject customer data access requests.", - "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", - "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "556e2733-6ca9-4edd-9cc7-26de66d46c2e", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-caching", + "service": "Front Door", "services": [ - "SQL" + "FrontDoor" ], - "severity": "Low", - "subcategory": "Lockbox", - "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", - "waf": "Security" + "severity": "Medium", + "subcategory": "Front Door", + "text": "Optimize your application query string for caching. For purely static content, ignore query strings to maximize your use of the cache. If your application uses query strings, consider including them in the cache key. Including the query strings in the cache key allows Azure Front Door to serve cached responses or other responses, based on your configuration.", + "waf": "Performance" }, { - "category": "Privileged Access", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "The principle of least privilege states that users shouldn't have more privileges than needed to complete their tasks. High-privileged database and server users can perform many configuration and maintenance activities on the database and can also drop databases in Azure SQL instance. Tracking database owners and privileged accounts is important to avoid having excessive permission.", - "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "c0b7e55e-fcab-4e66-bdae-bd0290f6aece", + "link": "https://learn.microsoft.com/azure/frontdoor/standard-premium/how-to-compression", + "service": "Front Door", "services": [ - "SQL" + "Storage", + "FrontDoor" ], "severity": "Medium", - "subcategory": "Permissions", - "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", - "waf": "Security" + "subcategory": "Front Door", + "text": "Use file compression when you're accessing downloadable content.", + "waf": "Performance" }, { - "category": "Privileged Access", - "checklist": "Azure SQLDB Security Checklist (Preview)", - "description": "Identities (both Users and SPNs) should be scoped to the least amount of access needed to perform the function. A higher number of tightly scoped SPNs should be used, instead of having one SPN with multiple sets of unrelated permissions. For example, if there are three external web applications hosted on-prem that make queries to the Azure SQL Database, they should not all use the same SPN for these activities. Instead, they should each have their own tightly scoped SPN.", - "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.network/frontdoors' and properties['resourceState'] !~ 'migrated' | extend compliant = false | project id, compliant", + "guid": "cb8eb8c0-aa73-4a26-a495-6eba8dc4a243", + "link": "https://learn.microsoft.com/azure/cdn/tier-migration", + "service": "Front Door", "services": [ - "Entra", - "SQL" + "FrontDoor" ], - "severity": "Low", - "subcategory": "Permissions", - "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", + "severity": "High", + "subcategory": "Front Door", + "text": "Consider migrating to Standard or Premium SKU if you are using Classic Azure Front Door currently as Classic Azure Front Door will be deprecated by March 2027.", + "waf": "Operations" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "67c33697-15b1-4752-aeee-0b9b588defc4", + "link": "https://learn.microsoft.com/azure/architecture/guide/networking/global-web-applications/mission-critical-content-delivery", + "service": "Front Door", + "services": [ + "Storage", + "TrafficManager", + "FrontDoor" + ], + "severity": "Medium", + "subcategory": "Front Door", + "text": "Consider using Traffic Manager load balancing Azure Front Door and a third party CDN provider CDN profile for mission critical high availability scenario. ", + "waf": "Reliability" + }, + { + "category": "Network Topology and Connectivity", + "checklist": "Azure Application Delivery Networking", + "guid": "972cd4cd-25b0-4b70-96e9-eab4bfd32907", + "link": "https://learn.microsoft.com/azure/app-service/app-service-ip-restrictions?tabs=azurecli#restrict-access-to-a-specific-azure-front-door-instance", + "service": "Front Door", + "services": [ + "AppSvc", + "FrontDoor" + ], + "severity": "High", + "subcategory": "Front Door", + "text": "When using Front Door with origin as App services, consider locking down the traffic to app services only through Azure Front Door using access restrictions. ", "waf": "Security" }, { @@ -11157,8 +11399,8 @@ "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Low", "subcategory": "High Availability", @@ -11172,8 +11414,8 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "service": "ACR", "services": [ - "ACR", - "AKS" + "AKS", + "ACR" ], "severity": "High", "subcategory": "High Availability", @@ -11215,8 +11457,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/aks/eslz-cost-governance-with-kubecost", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Low", "subcategory": "Cost", @@ -11230,8 +11472,8 @@ "link": "https://learn.microsoft.com/azure/aks/scale-down-mode", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Low", "subcategory": "Cost", @@ -11245,8 +11487,8 @@ "link": "https://learn.microsoft.com/azure/aks/gpu-multi-instance", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Medium", "subcategory": "Cost", @@ -11260,8 +11502,8 @@ "link": "https://learn.microsoft.com/azure/aks/start-stop-nodepools", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Low", "subcategory": "Cost", @@ -11320,8 +11562,8 @@ "link": "https://learn.microsoft.com/azure/container-registry/", "service": "AKS", "services": [ - "ACR", - "AKS" + "AKS", + "ACR" ], "severity": "Medium", "subcategory": "Compliance", @@ -11450,8 +11692,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-enable", "service": "AKS", "services": [ - "Defender", "AKV", + "Defender", "AKS" ], "severity": "Medium", @@ -11651,9 +11893,9 @@ "link": "https://azure.github.io/application-gateway-kubernetes-ingress/setup/install-existing/", "service": "AKS", "services": [ - "ACR", "AppGW", - "AKS" + "AKS", + "ACR" ], "severity": "Medium", "subcategory": "Best practices", @@ -11712,8 +11954,8 @@ "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-node-pool-with-a-unique-subnet", "service": "AKS", "services": [ - "AKS", - "VNet" + "VNet", + "AKS" ], "severity": "Medium", "subcategory": "Best practices", @@ -11727,10 +11969,10 @@ "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", "service": "AKS", "services": [ - "Cost", "PrivateLink", + "VNet", "AKS", - "VNet" + "Cost" ], "severity": "Medium", "subcategory": "Cost", @@ -11743,8 +11985,8 @@ "guid": "e8a03f97-8794-468d-96a7-86d60f96c97b", "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", "services": [ - "VPN", - "AKS" + "AKS", + "VPN" ], "severity": "Medium", "subcategory": "HA", @@ -11773,8 +12015,8 @@ "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "service": "AKS", "services": [ - "AKS", - "VNet" + "VNet", + "AKS" ], "severity": "High", "subcategory": "IPAM", @@ -11803,8 +12045,8 @@ "link": "https://learn.microsoft.com/azure/aks/internal-lb", "service": "AKS", "services": [ - "AKS", - "VNet" + "VNet", + "AKS" ], "severity": "Low", "subcategory": "IPAM", @@ -11903,8 +12145,8 @@ "link": "https://learn.microsoft.com/azure/aks/limit-egress-traffic", "service": "AKS", "services": [ - "NVA", - "AKS" + "AKS", + "NVA" ], "severity": "High", "subcategory": "Security", @@ -11995,8 +12237,8 @@ "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", "service": "AKS", "services": [ - "AKS", - "WAF" + "WAF", + "AKS" ], "severity": "High", "subcategory": "Security", @@ -12011,9 +12253,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/ddos-protection-overview", "service": "AKS", "services": [ + "VNet", "DDoS", - "AKS", - "VNet" + "AKS" ], "severity": "Medium", "subcategory": "Security", @@ -12285,8 +12527,8 @@ "link": "https://learn.microsoft.com/azure/aks/spot-node-pool", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Low", "subcategory": "Cost", @@ -12301,8 +12543,8 @@ "link": "https://learn.microsoft.com/azure/aks/concepts-scale", "service": "AKS", "services": [ - "Cost", - "AKS" + "AKS", + "Cost" ], "severity": "Low", "subcategory": "Cost", @@ -12378,10 +12620,10 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance", "service": "AKS", "services": [ - "Monitor", - "EventHubs", "AKS", + "EventHubs", "Storage", + "Monitor", "ServiceBus" ], "severity": "Medium", @@ -12396,10 +12638,10 @@ "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", "service": "AKS", "services": [ - "NVA", - "LoadBalancer", "Monitor", - "AKS" + "LoadBalancer", + "AKS", + "NVA" ], "severity": "Medium", "subcategory": "Monitoring", @@ -12456,8 +12698,8 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "service": "AKS", "services": [ - "AKS", - "Subscriptions" + "Subscriptions", + "AKS" ], "severity": "High", "subcategory": "Resources", @@ -13458,8 +13700,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/monitoring#set-up-alerts", "service": "Azure OpenAI", "services": [ - "AKV", "Monitor", + "AKV", "Subscriptions" ], "severity": "High", @@ -13824,8 +14066,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/ai-onboarding", "service": "Azure OpenAI", "services": [ - "Sentinel", "Monitor", + "Sentinel", "Defender" ], "severity": "High", @@ -13964,8 +14206,8 @@ "guid": "ac8ac199-ebb9-41a3-9d90-cae2cc881370", "service": "Azure OpenAI", "services": [ - "Firewall", - "VNet" + "VNet", + "Firewall" ], "severity": "High", "subcategory": "Network security", @@ -14217,8 +14459,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs", "service": "Azure OpenAI", "services": [ - "Cost", - "Monitor" + "Monitor", + "Cost" ], "severity": "Medium", "subcategory": "Cost monitoring", @@ -14274,8 +14516,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/provisioned-throughput-onboarding#understanding-the-provisioned-throughput-purchase-model", "service": "Azure OpenAI", "services": [ - "Cost", - "Storage" + "Storage", + "Cost" ], "severity": "High", "subcategory": "Costing Model", @@ -14388,10 +14630,10 @@ "link": "https://github.com/Azure/aoai-apim/blob/main/README.md", "service": "Azure OpenAI", "services": [ - "ACR", "LoadBalancer", "Entra", - "APIM" + "APIM", + "ACR" ], "severity": "Medium", "subcategory": "Load Balancing", @@ -14587,304 +14829,6 @@ "text": "Consider using dedicated model deployments per consumer group to provide per-model usage isolation that can help prevent noisy neighbors between your consumer groups", "waf": "Operational Excellence" }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", - "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", - "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", - "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", - "service": "ACR", - "services": [ - "ACR" - ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Disable Azure Container Registry image export", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", - "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", - "service": "ACR", - "services": [ - "ACR", - "AzurePolicy" - ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Enable Azure Policies for Azure Container Registry", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", - "guid": "d345293c-7639-4637-a551-c5c04e401955", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", - "service": "ACR", - "services": [ - "ACR", - "AKV" - ], - "severity": "High", - "subcategory": "Data Protection", - "text": "Sign and Verify containers with notation (Notary v2)", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", - "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", - "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", - "service": "ACR", - "services": [ - "ACR", - "AKV" - ], - "severity": "Medium", - "subcategory": "Data Protection", - "text": "Encrypt registry with a customer managed key", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", - "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "service": "ACR", - "services": [ - "ACR", - "RBAC", - "Entra" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Use Managed Identities to connect instead of Service Principals", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "guid": "be0e38ce-e297-411b-b363-caaab79b198d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "service": "ACR", - "services": [ - "ACR", - "RBAC", - "Entra" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable local authentication for management plane access", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", - "service": "ACR", - "services": [ - "ACR", - "RBAC", - "Entra" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable anonymous pull/push access", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", - "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", - "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", - "service": "ACR", - "services": [ - "ACR", - "Entra" - ], - "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Disable Anonymous pull access", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", - "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", - "service": "ACR", - "services": [ - "ACR", - "Entra" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Disable repository-scoped access tokens", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", - "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", - "service": "ACR", - "services": [ - "ACR", - "EventHubs", - "Entra", - "PrivateLink" - ], - "severity": "High", - "subcategory": "Identity and Access Control", - "text": "Deploy images from a trusted environment", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", - "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", - "service": "ACR", - "services": [ - "ACR", - "AzurePolicy", - "Entra" - ], - "severity": "Medium", - "subcategory": "Identity and Access Control", - "text": "Disable Azure ARM audience tokens for authentication", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", - "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", - "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", - "service": "ACR", - "services": [ - "ACR", - "Monitor", - "Entra" - ], - "severity": "Medium", - "subcategory": "Logging and Monitoring", - "text": "Enable diagnostics logging", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", - "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", - "service": "ACR", - "services": [ - "ACR", - "PrivateLink", - "Firewall", - "VNet" - ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Control inbound network access with Private Link", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Disable public network access if inbound network access is secured using Private Link", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", - "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", - "service": "ACR", - "services": [ - "ACR", - "PrivateLink" - ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Disable Public Network access", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Only the ACR Premium SKU supports Private Link access", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", - "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", - "service": "ACR", - "services": [ - "ACR", - "PrivateLink" - ], - "severity": "Medium", - "subcategory": "Network Security", - "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", - "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", - "service": "ACR", - "services": [ - "ACR", - "Defender" - ], - "severity": "Low", - "subcategory": "Network Security", - "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", - "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", - "service": "ACR", - "services": [ - "ACR" - ], - "severity": "Medium", - "subcategory": "Vulnerability Management", - "text": "Deploy validated container images", - "waf": "Security" - }, - { - "category": "Security", - "checklist": "Azure Container Registry Security Review", - "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", - "guid": "4e401955-387e-45ce-b126-cd132af5b20c", - "service": "ACR", - "services": [ - "ACR" - ], - "severity": "High", - "subcategory": "Vulnerability Management", - "text": "Use up-to-date platforms, languages, protocols and frameworks", - "waf": "Security" - }, { "category": "BC and DR", "checklist": "Azure Data Explorer Review Checklist", @@ -14893,8 +14837,8 @@ "link": "https://learn.microsoft.com/azure/data-explorer/kusto/management/data-export/continuous-data-export", "service": "Azure Data Explorer", "services": [ - "Cost", - "Storage" + "Storage", + "Cost" ], "subcategory": "Replication", "text": "Leverage External Tables and Continuous data export overview to reduce costs", @@ -15001,10 +14945,10 @@ "link": "https://learn.microsoft.com/azure/data-explorer/business-continuity-overview#on-demand-data-recovery-configuration", "service": "Azure Data Explorer", "services": [ - "Cost", "Storage", "ASR", - "AzurePolicy" + "AzurePolicy", + "Cost" ], "subcategory": "DR Configuration", "text": "For applications, where cost is a concern and can withstand some downtime during failure, create on-demand data recovery cluster configuration", @@ -15055,8 +14999,8 @@ "guid": "a96b96ad-8840-48f3-9273-4c876ba28021", "link": "https://learn.microsoft.com/azure/dns/private-dns-resiliency", "services": [ - "DNS", - "VNet" + "VNet", + "DNS" ], "severity": "High", "subcategory": "Azure Private DNS", @@ -15082,8 +15026,8 @@ "guid": "74faa19b-f39d-495d-94c7-c8919ca1f6d5", "link": "https://learn.microsoft.com/azure/reliability/reliability-traffic-manager?toc=%2Fazure%2Fdns%2Ftoc.json", "services": [ - "TrafficManager", "ASR", + "TrafficManager", "DNS" ], "severity": "Medium", @@ -15228,15 +15172,71 @@ "text": "If using Keyvault integration, use SLA of Keyvault to understand your availablity", "waf": "Reliability" }, + { + "category": "BC and DR", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "services": [ + "ACR" + ], + "severity": "High", + "subcategory": "High Availability", + "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", + "waf": "Reliability" + }, + { + "category": "BC and DR", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "services": [ + "Storage" + ], + "severity": "Medium", + "subcategory": "High Availability", + "text": "Configure data persistence for an Azure Cache for Redis instance. Because your cache data is stored in memory, a rare and unplanned failure of multiple nodes can cause all the data to be dropped. To avoid losing data completely, Redis persistence allows you to take periodic snapshots of in-memory data, and store it to your storage account.", + "waf": "Reliability" + }, + { + "category": "BC and DR", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "services": [ + "Storage" + ], + "severity": "Medium", + "subcategory": "High Availability", + "text": "Use Geo-redundant storage account to persist Azure Cache for Redis data, or zonally redundant where geo-redundancy is not available", + "waf": "Reliability" + }, + { + "category": "BC and DR", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "services": [ + "ASR" + ], + "severity": "Medium", + "subcategory": "High Availability", + "text": "Configure passive geo-replication for Premium Azure Cache for Redis instances. Geo-replication is a mechanism for linking two or more Azure Cache for Redis instances, typically spanning two Azure regions. Geo-replication is designed mainly for cross-region disaster recovery. Two Premium tier cache instances are connected through geo-replication in a way that provides reads and writes to your primary cache, and that data is replicated to the secondary cache.", + "waf": "Reliability" + }, { "category": "Identity", "checklist": "Azure VMware Solution Design Review", "guid": "32e42e36-11c8-418b-8a0b-c510e43a18a9", "service": "AVS", "services": [ - "AVS", + "Subscriptions", "Entra", - "Subscriptions" + "AVS" ], "severity": "High", "subcategory": "Identity", @@ -15249,8 +15249,8 @@ "guid": "75089c20-990d-4927-b105-885576f76fc2", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Identity", @@ -15263,8 +15263,8 @@ "guid": "de3aad1e-7c28-4ec9-9666-b7570449aa80", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Identity", @@ -15277,8 +15277,8 @@ "guid": "cd289ced-6b17-4db8-8554-61e2aee3553a", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Identity", @@ -15291,8 +15291,8 @@ "guid": "b9d37dac-43bc-46cd-8d79-a9b24604489a", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Identity", @@ -15305,8 +15305,8 @@ "guid": "53d88e89-d17b-473b-82a5-a67e7a9ed5b3", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Identity", @@ -15320,8 +15320,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Identity", @@ -15335,8 +15335,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Identity", @@ -15350,8 +15350,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Identity", @@ -15365,8 +15365,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Identity", @@ -15393,11 +15393,11 @@ "guid": "eb710a37-cbc1-4055-8dd5-a936a8bb7cf5", "service": "AVS", "services": [ - "ExpressRoute", "AVS", - "Monitor", + "NetworkWatcher", + "ExpressRoute", "VPN", - "NetworkWatcher" + "Monitor" ], "severity": "High", "subcategory": "Monitoring", @@ -15410,11 +15410,11 @@ "guid": "976e24f2-a7f8-426c-9253-2a92a2a7ed99", "service": "AVS", "services": [ - "ExpressRoute", "AVS", - "Monitor", + "NetworkWatcher", "VM", - "NetworkWatcher" + "ExpressRoute", + "Monitor" ], "severity": "Medium", "subcategory": "Monitoring", @@ -15427,10 +15427,10 @@ "guid": "f41ce6a0-64f3-4805-bc65-3ab50df01265", "service": "AVS", "services": [ - "VM", "Monitor", - "AVS", - "NetworkWatcher" + "VM", + "NetworkWatcher", + "AVS" ], "severity": "Medium", "subcategory": "Monitoring", @@ -15458,8 +15458,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Security (identity)", @@ -15473,8 +15473,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Security (identity)", @@ -15487,8 +15487,8 @@ "guid": "78c447a8-26b2-4863-af0f-1cac599ef1d5", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security (identity)", @@ -15501,8 +15501,8 @@ "guid": "8defc4d7-21d3-41d2-90fb-707ae9eab40e", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Security (identity)", @@ -15516,8 +15516,8 @@ "service": "AVS", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security (identity)", @@ -15530,8 +15530,8 @@ "guid": "9dd24429-eb72-4281-97a1-51c5bb4e4f18", "service": "AVS", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security (identity)", @@ -15545,8 +15545,8 @@ "service": "AVS", "services": [ "VM", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "High", "subcategory": "Security (identity)", @@ -15572,9 +15572,9 @@ "guid": "a2adb1c3-d232-46af-825c-a44e1695fddd", "service": "AVS", "services": [ + "Firewall", "AppGW", - "AVS", - "Firewall" + "AVS" ], "severity": "High", "subcategory": "Security (network)", @@ -15615,11 +15615,11 @@ "guid": "334fdf91-c234-4182-a652-75269440b4be", "service": "AVS", "services": [ - "ExpressRoute", + "DDoS", "AVS", + "ExpressRoute", "VPN", - "VNet", - "DDoS" + "VNet" ], "severity": "Medium", "subcategory": "Security (network)", @@ -15673,8 +15673,8 @@ "guid": "85e12139-bd7b-4b01-8f7b-95ef6e043e2a", "service": "AVS", "services": [ - "AVS", - "SQL" + "SQL", + "AVS" ], "severity": "Low", "subcategory": "Security (guest/VM)", @@ -15728,8 +15728,8 @@ "service": "AVS", "services": [ "Storage", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "High", "subcategory": "Governance (platform)", @@ -15769,8 +15769,8 @@ "guid": "bf39d95d-44c7-4c89-89ca-1f6d5315ae52", "service": "AVS", "services": [ - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Governance (platform)", @@ -15783,8 +15783,8 @@ "guid": "4ba34d45-85e1-4213-abd7-bb012f7b95ef", "service": "AVS", "services": [ - "Cost", - "AVS" + "AVS", + "Cost" ], "severity": "Medium", "subcategory": "Governance (platform)", @@ -15797,8 +15797,8 @@ "guid": "6e043e2a-a359-4271-ae6e-205172676ae4", "service": "AVS", "services": [ - "Cost", - "AVS" + "AVS", + "Cost" ], "severity": "Low", "subcategory": "Governance (platform)", @@ -15837,8 +15837,8 @@ "guid": "48b262d6-cc5f-4512-a253-98e6db9d37da", "service": "AVS", "services": [ - "Defender", "VM", + "Defender", "AVS" ], "severity": "Medium", @@ -15852,8 +15852,8 @@ "guid": "41741583-3ef7-4ad7-a6d3-733165c7acbe", "service": "AVS", "services": [ - "Arc", "VM", + "Arc", "AVS" ], "severity": "Medium", @@ -15880,8 +15880,8 @@ "guid": "4ed90dae-2cc8-44c4-9b6b-781cbafe6c46", "service": "AVS", "services": [ - "VM", "Monitor", + "VM", "AVS" ], "severity": "Medium", @@ -15895,10 +15895,10 @@ "guid": "589d457a-927c-4397-9d11-02cad6aae11e", "service": "AVS", "services": [ + "AzurePolicy", "VM", "Backup", - "AVS", - "AzurePolicy" + "AVS" ], "severity": "Medium", "subcategory": "Governance (guest/VM)", @@ -15911,8 +15911,8 @@ "guid": "ee29711b-d352-4caa-ab79-b198dab81932", "service": "AVS", "services": [ - "Defender", "Monitor", + "Defender", "AVS" ], "severity": "Medium", @@ -16068,9 +16068,9 @@ "service": "AVS", "services": [ "Storage", + "AzurePolicy", "VM", - "AVS", - "AzurePolicy" + "AVS" ], "severity": "High", "subcategory": "Operations", @@ -16153,8 +16153,8 @@ "service": "AVS", "services": [ "Monitor", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Operations", @@ -16265,10 +16265,10 @@ "guid": "d1d79a9b-2460-4448-aa8f-42d78e78cb6a", "service": "AVS", "services": [ - "NVA", - "ASR", "ExpressRoute", - "AVS" + "ASR", + "AVS", + "NVA" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -16388,8 +16388,8 @@ "guid": "0f1cac6d-9ef1-4d5e-a32e-42e3611c818b", "service": "AVS", "services": [ - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Low", "subcategory": "Automated Deployment", @@ -16416,8 +16416,8 @@ "guid": "255461e2-aee3-4553-afc8-339248b262d6", "service": "AVS", "services": [ - "AKV", "ExpressRoute", + "AKV", "AVS" ], "severity": "Low", @@ -16457,8 +16457,8 @@ "guid": "3bd2a0a1-7e7a-48d9-8ae0-e37cee29711b", "service": "AVS", "services": [ - "AVS", - "Subscriptions" + "Subscriptions", + "AVS" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -16472,8 +16472,8 @@ "service": "AVS", "services": [ "Storage", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -16570,8 +16570,8 @@ "guid": "bc91a43d-90da-4e2c-a881-4706f7c1cbaf", "service": "AVS", "services": [ - "VPN", - "AVS" + "AVS", + "VPN" ], "severity": "Medium", "subcategory": "Networking", @@ -16627,9 +16627,9 @@ "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", "service": "AVS", "services": [ - "Storage", "ExpressRoute", - "AVS" + "AVS", + "Storage" ], "severity": "Medium", "subcategory": "Architecture", @@ -16643,9 +16643,9 @@ "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", "service": "AVS", "services": [ - "Storage", "ExpressRoute", - "AVS" + "AVS", + "Storage" ], "severity": "Medium", "subcategory": "Architecture", @@ -16773,8 +16773,8 @@ "link": "https://learn.microsoft.com/azure/reliability/reliability-azure-container-apps?tabs=azure-cli#cross-region-disaster-recovery-and-business-continuity", "service": "Container Apps", "services": [ - "FrontDoor", "TrafficManager", + "FrontDoor", "WAF" ], "severity": "High", @@ -17210,8 +17210,8 @@ "service": "VM", "services": [ "Storage", - "VM", "SQL", + "VM", "WAF" ], "severity": "Medium", @@ -17226,10 +17226,10 @@ "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "service": "VM", "services": [ - "ACR", "Storage", "VM", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Leverage Availability Zones for your VMs in regions where they are supported", @@ -17258,8 +17258,8 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/availability", "service": "VM", "services": [ - "VM", "ASR", + "VM", "WAF" ], "severity": "High", @@ -17274,8 +17274,8 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "service": "VM", "services": [ - "VM", "ASR", + "VM", "AVS", "WAF" ], @@ -17305,8 +17305,8 @@ "link": "https://learn.microsoft.com/azure/quotas/per-vm-quota-requests", "service": "VM", "services": [ - "VM", "ASR", + "VM", "WAF" ], "severity": "Medium", @@ -17442,10 +17442,10 @@ "link": "https://learn.microsoft.com/azure/dns/tutorial-dns-private-resolver-failover", "service": "DNS", "services": [ - "ACR", "ASR", "DNS", - "WAF" + "WAF", + "ACR" ], "severity": "Low", "text": "Implement DNS Failover using Azure DNS Private Resolvers", @@ -17459,8 +17459,8 @@ "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-high-availability-clusters", "service": "Data Gateways", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use on-premises data gateway clusters to ensure high availability for business-critical data", @@ -17474,8 +17474,8 @@ "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "service": "NVA", "services": [ - "NVA", - "WAF" + "WAF", + "NVA" ], "severity": "High", "text": "Deploy Network Virtual Appliances (NVAs) in a vendor supported configuration for High Availability", @@ -17506,8 +17506,8 @@ "service": "Azure Storage", "services": [ "Storage", - "PrivateLink", - "WAF" + "WAF", + "PrivateLink" ], "severity": "High", "text": "Consider using private endpoints for Azure Storage", @@ -17521,10 +17521,10 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", "service": "Azure Storage", "services": [ - "Subscriptions", "Storage", - "RBAC", - "WAF" + "Subscriptions", + "WAF", + "RBAC" ], "severity": "Medium", "text": "Ensure older storage accounts are not using 'classic deployment model'", @@ -17630,8 +17630,8 @@ "service": "Azure Storage", "services": [ "Storage", - "Subscriptions", "AzurePolicy", + "Subscriptions", "WAF" ], "severity": "High", @@ -17755,11 +17755,11 @@ "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", "service": "Azure Storage", "services": [ - "Monitor", - "AKV", - "Storage", "WAF", - "Entra" + "Storage", + "Entra", + "Monitor", + "AKV" ], "severity": "High", "text": "Consider disabling storage account keys, so that only Microsoft Entra ID access (and user delegation SAS) is supported.", @@ -17773,11 +17773,11 @@ "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", "service": "Azure Storage", "services": [ - "Monitor", - "AKV", - "Storage", "WAF", - "AzurePolicy" + "AzurePolicy", + "Storage", + "Monitor", + "AKV" ], "severity": "High", "text": "Consider using Azure Monitor to audit control plane operations on the storage account", @@ -17792,8 +17792,8 @@ "service": "Azure Storage", "services": [ "Storage", - "AKV", "AzurePolicy", + "AKV", "WAF" ], "severity": "Medium", @@ -17824,8 +17824,8 @@ "service": "Azure Storage", "services": [ "Storage", - "AKV", "AzurePolicy", + "AKV", "WAF" ], "severity": "Medium", @@ -17930,9 +17930,9 @@ "service": "Azure Storage", "services": [ "Storage", - "RBAC", "Entra", - "WAF" + "WAF", + "RBAC" ], "severity": "High", "text": "SFTP: Limit the amount of 'local users' for SFTP access, and audit whether access is needed over time.", @@ -18151,12 +18151,12 @@ "link": "https://learn.microsoft.com/azure/reliability/cross-region-replication-azure", "service": "SAP", "services": [ - "ASR", + "WAF", "Backup", - "Storage", "SAP", - "SQL", - "WAF" + "Storage", + "ASR", + "SQL" ], "severity": "High", "text": "You can replicate standard storage between paired regions, but you can't use standard storage to store your databases or virtual hard disks. You can replicate backups only between paired regions that you use. For all your other data, run your replication by using native DBMS features like SQL Server Always On or SAP HANA System Replication. Use a combination of Site Recovery, rsync or robocopy, and other third-party software for the SAP application layer.", @@ -18184,10 +18184,10 @@ "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", "service": "SAP", "services": [ - "ASR", "ExpressRoute", - "VPN", - "WAF" + "ASR", + "WAF", + "VPN" ], "severity": "High", "text": "Set up ExpressRoute connections from on-premises to the primary and secondary Azure disaster recovery regions. Also, as an alternative to using ExpressRoute, consider setting up VPN connections from on-premises to the primary and secondary Azure disaster recovery regions.", @@ -18200,9 +18200,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", "service": "SAP", "services": [ - "ACR", "AKV", - "WAF" + "WAF", + "ACR" ], "severity": "Low", "text": "Replicate key vault contents like certificates, secrets, or keys across regions so you can decrypt data in the DR region.", @@ -18214,8 +18214,8 @@ "link": "https://learn.microsoft.com/azure/architecture/guide/sap/sap-s4hana", "service": "SAP", "services": [ - "VNet", "ASR", + "VNet", "SAP", "WAF" ], @@ -18271,8 +18271,8 @@ "guid": "0258ed30-fe42-434f-87b9-58f91f908e0a", "service": "SAP", "services": [ - "VM", "ASR", + "VM", "Entra", "WAF" ], @@ -18402,8 +18402,8 @@ "link": "https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services?lang=1", "service": "SAP", "services": [ - "VM", "SAP", + "VM", "Entra", "WAF" ], @@ -18417,8 +18417,8 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/availability-set-overview", "service": "SAP", "services": [ - "VM", "RBAC", + "VM", "Entra", "WAF" ], @@ -18474,9 +18474,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/proximity-placement-scenarios", "service": "SAP", "services": [ - "ACR", "SAP", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Use one proximity placement group per SAP SID. Groups don't span across Availability Zones or Azure regions", @@ -18606,9 +18606,9 @@ "link": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/optimize-your-azure-costs-by-automating-sap-system-start-stop/ba-p/2120675", "service": "SAP", "services": [ - "Cost", "SAP", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Automate SAP System Start-Stop to manage costs.", @@ -18620,11 +18620,11 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/hana-vm-premium-ssd-v1", "service": "SAP", "services": [ + "WAF", "Cost", - "Storage", + "VM", "SAP", - "WAF", - "VM" + "Storage" ], "severity": "Low", "text": "In the case of using Azure Premium Storage with SAP HANA, Azure Standard SSD storage can be used to select a cost-conscious storage solution. However, please note that choosing Standard SSD or Standard HDD Azure storage will affect the SLA of the individual VMs. Also, for systems with lower I/O throughput and low latency, such as non-production environments, lower series VMs can be used.", @@ -18636,11 +18636,11 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/hana-vm-premium-ssd-v1", "service": "SAP", "services": [ + "WAF", "Cost", - "Storage", + "VM", "SAP", - "WAF", - "VM" + "Storage" ], "severity": "Low", "text": "As a lower-cost alternative configuration (multipurpose), you can choose a low-performance SKU for your non-production HANA database server VMs. However, it is important to note that some VM types, such as E-series, are not HANA certified (SAP HANA Hardware Directory) or cannot achieve storage latency of less than 1ms.", @@ -18653,8 +18653,8 @@ "link": "https://learn.microsoft.com/azure/well-architected/sap/design-areas/security", "service": "SAP", "services": [ - "Subscriptions", "RBAC", + "Subscriptions", "WAF" ], "severity": "High", @@ -18862,9 +18862,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups", "service": "SAP", "services": [ + "AzurePolicy", "Subscriptions", "SAP", - "AzurePolicy", "WAF" ], "severity": "Medium", @@ -18910,8 +18910,8 @@ "link": "https://learn.microsoft.com/azure/quotas/quotas-overview", "service": "SAP", "services": [ - "Subscriptions", "VM", + "Subscriptions", "WAF" ], "severity": "High", @@ -18937,8 +18937,8 @@ "link": "https://learn.microsoft.com/azure/quotas/quickstart-increase-quota-portal", "service": "SAP", "services": [ - "Subscriptions", "VM", + "Subscriptions", "WAF" ], "severity": "High", @@ -18965,9 +18965,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-resource-organization", "service": "SAP", "services": [ - "Cost", "TrafficManager", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Leverage Azure resource tag for cost categorization and resource grouping (: BillTo, Department (or Business Unit), Environment (Production, Stage, Development), Tier (Web Tier, Application Tier), Application Owner, ProjectName)", @@ -19036,8 +19036,8 @@ "link": "https://azure.microsoft.com/pricing/offers/dev-test/", "service": "SAP", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Low", "text": "Consider running dev/test systems in a snooze model to save and optimize Azure run costs.", @@ -19091,9 +19091,9 @@ "link": "https://learn.microsoft.com/azure/sap/monitor/about-azure-monitor-sap-solutions", "service": "SAP", "services": [ - "SAP", "Monitor", "SQL", + "SAP", "WAF" ], "severity": "Medium", @@ -19107,11 +19107,11 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/vm-extension-for-sap", "service": "SAP", "services": [ - "Monitor", - "SAP", "WAF", "VM", - "Entra" + "SAP", + "Entra", + "Monitor" ], "severity": "High", "text": "Run a VM Extension for SAP check. VM Extension for SAP uses the assigned managed identity of a virtual machine (VM) to access VM monitoring and configuration data. The check ensures that all performance metrics in your SAP application come from the underlying Azure Extension for SAP.", @@ -19138,9 +19138,9 @@ "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-overview", "service": "SAP", "services": [ - "SAP", - "NetworkWatcher", "Monitor", + "NetworkWatcher", + "SAP", "WAF" ], "severity": "Medium", @@ -19198,9 +19198,9 @@ "link": "https://learn.microsoft.com/azure/sentinel/sap/deployment-overview", "service": "SAP", "services": [ + "Monitor", "Sentinel", "SAP", - "Monitor", "WAF" ], "severity": "Medium", @@ -19215,8 +19215,8 @@ "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/enable-tag-inheritance", "service": "SAP", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Azure tagging can be leveraged to logically group and track resources, automate their deployments, and most importantly, provide visibility on the incurred costs.", @@ -19229,8 +19229,8 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-test-latency?tabs=windows", "service": "SAP", "services": [ - "VM", "Monitor", + "VM", "WAF" ], "severity": "Low", @@ -19243,9 +19243,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide-storage", "service": "SAP", "services": [ + "Monitor", "ASR", "SAP", - "Monitor", "WAF" ], "severity": "Medium", @@ -19301,8 +19301,8 @@ "link": "https://techcommunity.microsoft.com/t5/running-sap-applications-on-the/announcement-sap-on-azure-oracle-performance-efficiency-scripts/ba-p/3725178", "service": "SAP", "services": [ - "SAP", "SQL", + "SAP", "WAF" ], "severity": "Medium", @@ -19316,9 +19316,9 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-monitor-and-troubleshoot", "service": "SAP", "services": [ + "Monitor", "ASR", "SAP", - "Monitor", "WAF" ], "severity": "High", @@ -19332,8 +19332,8 @@ "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "service": "SAP", "services": [ - "AppGW", "AzurePolicy", + "AppGW", "WAF" ], "severity": "Medium", @@ -19347,8 +19347,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", "service": "SAP", "services": [ - "DNS", "VM", + "DNS", "SAP", "WAF" ], @@ -19363,8 +19363,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-network-topology-and-connectivity", "service": "SAP", "services": [ - "DNS", "VNet", + "DNS", "SAP", "WAF" ], @@ -19381,10 +19381,10 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-peering-overview", "service": "SAP", "services": [ - "ACR", "VNet", "SAP", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Local and global VNet peering provide connectivity and are the preferred approaches to ensure connectivity between landing zones for SAP deployments across multiple Azure regions", @@ -19397,9 +19397,9 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/planning-guide", "service": "SAP", "services": [ - "NVA", "SAP", - "WAF" + "WAF", + "NVA" ], "severity": "High", "text": "It is not supported to deploy any NVA between SAP application and SAP Database server", @@ -19413,10 +19413,10 @@ "link": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/?source=recommendations", "service": "SAP", "services": [ - "ACR", - "SAP", "VWAN", - "WAF" + "SAP", + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Virtual WAN for Azure deployments in new, large, or global networks where you need global transit connectivity across Azure regions and on-premises locations. With this approach, you won't need to manually set up transitive routing for Azure networking, and you can follow a standard for SAP on Azure deployments.", @@ -19429,9 +19429,9 @@ "link": "https://learn.microsoft.com/azure/well-architected/services/networking/network-virtual-appliances/reliability", "service": "SAP", "services": [ - "NVA", "VNet", - "WAF" + "WAF", + "NVA" ], "severity": "Medium", "text": "Consider deploying network virtual appliances (NVAs) between regions only if partner NVAs are used. NVAs between regions or VNets aren't required if native NVAs are present. When you're deploying partner networking technologies and NVAs, follow the vendor's guidance to verify conflicting configurations with Azure networking.", @@ -19444,8 +19444,8 @@ "link": "https://learn.microsoft.com/azure/architecture/networking/hub-spoke-vwan-architecture", "service": "SAP", "services": [ - "NVA", "WAF", + "NVA", "VWAN", "SAP", "VNet" @@ -19535,8 +19535,8 @@ "link": "https://learn.microsoft.com/azure/sap/workloads/expose-sap-process-orchestration-on-azure", "service": "SAP", "services": [ - "AppGW", "SAP", + "AppGW", "WAF" ], "severity": "Medium", @@ -19550,10 +19550,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "SAP", "services": [ - "ACR", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Azure Front Door and WAF policies to provide global protection across Azure regions for inbound HTTP/S connections to a landing zone.", @@ -19566,10 +19566,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "service": "SAP", "services": [ - "AppGW", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Medium", "text": "Take advantage of Web Application Firewall policies in Azure Front Door when you're using Azure Front Door and Application Gateway to protect HTTP/S applications. Lock down Application Gateway to receive traffic only from Azure Front Door.", @@ -19582,8 +19582,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "SAP", "services": [ - "AppGW", "LoadBalancer", + "AppGW", "WAF" ], "severity": "Medium", @@ -19597,10 +19597,10 @@ "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", "service": "SAP", "services": [ - "ACR", - "SAP", "VWAN", - "WAF" + "SAP", + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Virtual WAN for Azure deployments in new, large, or global networks where you need global transit connectivity across Azure regions and on-premises locations. With this approach, you won't need to manually set up transitive routing for Azure networking, and you can follow a standard for SAP on Azure deployments.", @@ -19613,12 +19613,12 @@ "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", "service": "SAP", "services": [ - "ACR", + "PrivateLink", "WAF", + "ACR", "Backup", "Storage", - "VNet", - "PrivateLink" + "VNet" ], "severity": "Medium", "text": "To prevent data leakage, use Azure Private Link to securely access platform as a service resources like Azure Blob Storage, Azure Files, Azure Data Lake Storage Gen2, Azure Data Factory, and more. Azure Private Endpoint can also help to secure traffic between VNets and services like Azure Storage, Azure Backup, and more. Traffic between your VNet and the Private Endpoint enabled service travels across the Microsoft global network, which prevents its exposure to the public internet.", @@ -19721,10 +19721,10 @@ "link": "https://me.sap.com/notes/2015553", "service": "SAP", "services": [ - "Cost", "VNet", "SAP", - "WAF" + "WAF", + "Cost" ], "severity": "High", "text": "It isn't recommended to host the database management system (DBMS) and application layers of SAP systems in different VNets and connect them with VNet peering because of the substantial costs that excessive network traffic between the layers can produce. Recommend using subnets within the Azure virtual network to separate the SAP application layer and DBMS layer.", @@ -19766,8 +19766,8 @@ "service": "SAP", "services": [ "VM", - "SAP", "Backup", + "SAP", "WAF" ], "severity": "High", @@ -19780,9 +19780,9 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-monitor-and-troubleshoot", "service": "SAP", "services": [ + "Monitor", "ASR", "SAP", - "Monitor", "WAF" ], "severity": "Medium", @@ -19795,8 +19795,8 @@ "link": "https://help.sap.com/docs/SAP_HANA_PLATFORM/c4d7c773af4a4e5dbebb6548d6e2d4f4/e3111d2ebb5710149510cc120646bf3f.html?locale=en-US", "service": "SAP", "services": [ - "SAP", "Monitor", + "SAP", "WAF" ], "severity": "High", @@ -19930,8 +19930,8 @@ "link": "https://learn.microsoft.com/en-us/azure/sap/large-instances/hana-monitor-troubleshoot", "service": "SAP", "services": [ - "SAP", "Monitor", + "SAP", "WAF" ], "severity": "Medium", @@ -19985,8 +19985,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/sap-lza-database-security", "service": "SAP", "services": [ - "SAP", "SQL", + "SAP", "WAF" ], "severity": "Low", @@ -20013,11 +20013,11 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/sap/eslz-security-governance-and-compliance", "service": "SAP", "services": [ + "WAF", "Backup", - "Storage", "SAP", - "SQL", - "WAF" + "Storage", + "SQL" ], "severity": "High", "text": "Encrypting SAP HANA database servers on Azure uses SAP HANA native encryption technology. Additionally, if you are using SQL Server on Azure, use Transparent Data Encryption (TDE) to protect your data and log files and ensure that your backups are also encrypted.", @@ -20059,9 +20059,9 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/lock-resources?tabs=json", "service": "SAP", "services": [ - "Subscriptions", "RBAC", "AzurePolicy", + "Subscriptions", "WAF" ], "severity": "Medium", @@ -20075,8 +20075,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview", "service": "SAP", "services": [ - "AKV", "AzurePolicy", + "AKV", "WAF" ], "severity": "Medium", @@ -20121,9 +20121,9 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/just-in-time-access-overview?tabs=defender-for-container-arch-aks", "service": "SAP", "services": [ - "Defender", "RBAC", "SAP", + "Defender", "WAF" ], "severity": "High", @@ -20195,8 +20195,8 @@ "link": "https://learn.microsoft.com/azure/role-based-access-control/built-in-roles", "service": "SAP", "services": [ - "Subscriptions", "RBAC", + "Subscriptions", "SAP", "WAF" ], @@ -20211,10 +20211,10 @@ "link": "https://blogs.sap.com/2019/07/21/sap-security-operations-on-azure/", "service": "SAP", "services": [ - "NVA", "PrivateLink", "SAP", - "WAF" + "WAF", + "NVA" ], "severity": "High", "text": "Isolate DMZs and NVAs from the rest of the SAP estate, configure Azure Private Link, and securely manage and control the SAP on Azure resources", @@ -20285,9 +20285,9 @@ "link": "https://learn.microsoft.com/azure/sap/monitor/enable-tls-azure-monitor-sap-solutions", "service": "SAP", "services": [ + "Monitor", "AKV", "SAP", - "Monitor", "WAF" ], "severity": "Medium", @@ -20335,8 +20335,8 @@ "link": "https://learn.microsoft.com/azure/reliability/migrate-app-service", "service": "App Services", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Leverage Availability Zones where regionally applicable (Premium V2/V3 tier required). Check region support for Availability Zones.", @@ -20399,8 +20399,8 @@ "link": "https://learn.microsoft.com/azure/app-service/manage-disaster-recovery#recover-app-content-only", "service": "App Services", "services": [ - "ASR", "AppSvc", + "ASR", "WAF" ], "severity": "Low", @@ -20489,8 +20489,8 @@ "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", "service": "App Services", "services": [ - "AKV", "AppSvc", + "AKV", "WAF" ], "severity": "High", @@ -20505,8 +20505,8 @@ "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", "service": "App Services", "services": [ - "AKV", "AppSvc", + "AKV", "Entra", "WAF" ], @@ -20522,8 +20522,8 @@ "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", "service": "App Services", "services": [ - "AKV", "AppSvc", + "AKV", "Entra", "WAF" ], @@ -20539,8 +20539,8 @@ "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", "service": "App Services", "services": [ - "Subscriptions", "AppSvc", + "Subscriptions", "WAF" ], "severity": "Medium", @@ -20571,10 +20571,10 @@ "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", "service": "App Services", "services": [ - "ACR", "AppSvc", "Entra", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Microsoft Entra ID or B2C for secure authentication and Single Sign-On (SSO).", @@ -20634,9 +20634,9 @@ "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", "service": "App Services", "services": [ - "ACR", "Entra", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Pull container images from Azure Container Registry using a Managed Identity.", @@ -20651,9 +20651,9 @@ "service": "App Services", "services": [ "AppSvc", - "Monitor", "Entra", - "WAF" + "WAF", + "Monitor" ], "severity": "Medium", "text": "Send App Service runtime and security logs to Log Analytics for centralized monitoring and alerting.", @@ -20669,8 +20669,8 @@ "services": [ "AppSvc", "Monitor", - "Entra", - "WAF" + "WAF", + "Entra" ], "severity": "Medium", "text": "Send App Service activity logs to Log Analytics", @@ -20685,11 +20685,11 @@ "service": "App Services", "services": [ "AppSvc", - "Monitor", - "NVA", "WAF", - "Firewall", - "VNet" + "NVA", + "Monitor", + "VNet", + "Firewall" ], "severity": "Medium", "text": "Control outbound network access for App Service using VNet integration, NSGs, UDRs, and firewalls.", @@ -20703,12 +20703,12 @@ "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", "service": "App Services", "services": [ - "NVA", + "PrivateLink", "WAF", - "Firewall", + "NVA", "Storage", "VNet", - "PrivateLink" + "Firewall" ], "severity": "Low", "text": "Ensure a stable IP for outbound communications by using VNet NAT Gateway or Azure Firewall.", @@ -20739,10 +20739,10 @@ "service": "App Services", "services": [ "AppSvc", - "Monitor", "AppGW", "WAF", - "FrontDoor" + "FrontDoor", + "Monitor" ], "severity": "High", "text": "Use a Web Application Firewall (WAF) in front of App Service.", @@ -20756,9 +20756,9 @@ "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", "service": "App Services", "services": [ - "PrivateLink", "AppSvc", - "WAF" + "WAF", + "PrivateLink" ], "severity": "High", "text": "Ensure the WAF cannot be bypassed by securing access to App Service.", @@ -20836,8 +20836,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", "service": "App Services", "services": [ - "Defender", "AppSvc", + "Defender", "WAF" ], "severity": "Medium", @@ -20852,12 +20852,12 @@ "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "service": "App Services", "services": [ - "NVA", + "AppGW", + "DDoS", "WAF", + "NVA", "EventHubs", - "AppGW", - "VNet", - "DDoS" + "VNet" ], "severity": "Medium", "text": "Enable DDOS Protection Standard on the WAF VNet", @@ -20871,11 +20871,11 @@ "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", "service": "App Services", "services": [ - "ACR", "AppSvc", + "PrivateLink", "WAF", - "VNet", - "PrivateLink" + "ACR", + "VNet" ], "severity": "Medium", "text": "Pull container images over a Virtual Network from Azure Container Registry.", @@ -20961,10 +20961,10 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "service": "App Services", "services": [ - "ACR", "AppSvc", - "Backup", "WAF", + "ACR", + "Backup", "AzurePolicy" ], "severity": "High", @@ -20979,10 +20979,10 @@ "link": "https://learn.microsoft.com/azure/cost-management-billing/", "service": "App Services", "services": [ - "Cost", "AppSvc", "Monitor", - "WAF" + "WAF", + "Cost" ], "severity": "Low", "text": "Monitor App Service costs using Azure Cost Management and create cost alerts.", @@ -20997,10 +20997,10 @@ "service": "App Services", "services": [ "AppSvc", + "WAF", "Cost", "ARS", - "Storage", - "WAF" + "Storage" ], "severity": "Medium", "text": "Purchase reserved instances for App Service plans to optimize long-term costs.", @@ -21183,8 +21183,8 @@ "link": "https://learn.microsoft.com/azure/search/search-reliability#multiple-services-in-separate-geographic-regions", "service": "Cognitive Search", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "For regional redudancy, Manually create services in 2 or more regions for Search as it doesn't provide an automated method of replicating search indexes across geographic regions", @@ -21197,8 +21197,8 @@ "link": "https://learn.microsoft.com/azure/search/search-reliability#synchronize-data-across-multiple-services", "service": "Cognitive Search", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "To synchronize data across multiple services either Use indexers for updating content on multiple services or Use REST APIs for pushing content updates on multiple services", @@ -21322,8 +21322,8 @@ "service": "Azure Backup", "services": [ "Storage", - "Backup", "ASR", + "Backup", "WAF" ], "severity": "Medium", @@ -21415,10 +21415,10 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/manage/centralize-operations", "service": "VM", "services": [ - "Cost", - "VM", "AzurePolicy", - "WAF" + "VM", + "WAF", + "Cost" ], "severity": "Medium", "text": "run the script on all windows VMs https://learn.microsoft.com/azure/virtual-machines/windows/hybrid-use-benefit-licensing?ref=andrewmatveychuk.com#convert-an-existing-vm-using-azure-hybrid-benefit-for-windows-server- consider implementing a policy if windows VMs are created frequently", @@ -21460,10 +21460,10 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", "service": "VM", "services": [ - "Cost", - "VM", "ARS", - "WAF" + "VM", + "WAF", + "Cost" ], "severity": "Medium", "text": "Utilize Azure Reserved Instances: This feature allows you to reserve VMs for a period of 1 or 3 years, providing significant cost savings compared to PAYG prices.", @@ -21502,10 +21502,10 @@ "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", "service": "Azure SQL", "services": [ - "Cost", - "SQL", "AzurePolicy", - "WAF" + "SQL", + "WAF", + "Cost" ], "severity": "Medium", "text": "Check if applicable and enforce policy/change https://learn.microsoft.com/azure/azure-sql/azure-hybrid-benefit?view=azuresql&tabs=azure-portalhttps://learn.microsoft.com/azure/cost-management-billing/scope-level/create-sql-license-assignments?source=recommendations", @@ -21574,8 +21574,8 @@ "link": "https://learn.microsoft.com/azure/databricks/clusters/cluster-config-best-practices#automatic-termination", "service": "Databricks", "services": [ - "VM", "LoadBalancer", + "VM", "WAF" ], "severity": "Medium", @@ -21809,10 +21809,10 @@ "link": "https://learn.microsoft.com/azure/reliability/availability-zones-overview", "service": "Synapse", "services": [ - "Cost", - "EventHubs", "Monitor", - "WAF" + "EventHubs", + "WAF", + "Cost" ], "severity": "Medium", "text": "Create budgets to manage costs and create alerts that automatically notify stakeholders of spending anomalies and overspending risks.", @@ -21825,9 +21825,9 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/availability", "service": "Synapse", "services": [ - "Cost", "Storage", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Export cost data to a storage account for additional data analysis.", @@ -21840,9 +21840,9 @@ "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "service": "Synapse", "services": [ - "Cost", "SQL", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Control costs for a dedicated SQL pool by pausing the resource when it is not in use.", @@ -21881,8 +21881,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-groups-in-the-azure-landing-zone-accelerator", "service": "Synapse", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Purchase Azure Synapse commit units (SCU) for one year with a pre-purchase plan to save on your Azure Synapse Analytics costs.", @@ -21896,9 +21896,9 @@ "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", "service": "VM", "services": [ - "Cost", "VM", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Use Spot VMs for interruptible jobs: These are VMs that can be bid on and purchased at a discounted price, providing a cost-effective solution for non-critical workloads.", @@ -21941,8 +21941,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "VM", "services": [ - "VM", "Monitor", + "VM", "WAF" ], "severity": "Medium", @@ -21972,8 +21972,8 @@ "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", "service": "Redis", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", @@ -22045,8 +22045,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "Front Door", "services": [ - "FrontDoor", "AzurePolicy", + "FrontDoor", "WAF" ], "severity": "Medium", @@ -22061,10 +22061,10 @@ "link": "https://learn.microsoft.com/azure/frontdoor/origin-security?tabs=application-gateway&pivots=front-door-standard-premium#example-configuration", "service": "Front Door", "services": [ - "AppGW", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Medium", "text": "When using Front Door and Application Gateway to help protect HTTP/S apps, use WAF policies in Front Door. Lock down Application Gateway to receive traffic only from Front Door.", @@ -22079,8 +22079,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", "service": "Front Door", "services": [ - "FrontDoor", "AzurePolicy", + "FrontDoor", "WAF" ], "severity": "High", @@ -22096,8 +22096,8 @@ "service": "Front Door", "services": [ "EventHubs", - "FrontDoor", "TrafficManager", + "FrontDoor", "WAF" ], "severity": "High", @@ -22171,10 +22171,10 @@ "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", "service": "Front Door", "services": [ - "Cost", "AKV", "FrontDoor", - "WAF" + "WAF", + "Cost" ], "severity": "High", "text": "Use managed TLS certificates with Azure Front Door. Reduce operational cost and risk of outages due to certificate renewals.", @@ -22260,8 +22260,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", "service": "Front Door", "services": [ - "FrontDoor", "AzurePolicy", + "FrontDoor", "WAF" ], "severity": "High", @@ -22570,8 +22570,8 @@ "service": "Front Door", "services": [ "Storage", - "FrontDoor", "TrafficManager", + "FrontDoor", "WAF" ], "severity": "Medium", @@ -22655,8 +22655,8 @@ "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "service": "AKS", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Low", "text": "Use Disruption Budgets in your pod and deployment definitions", @@ -22669,8 +22669,8 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", "service": "ACR", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "If using a private registry, configure region replication to store images in multiple regions", @@ -22683,8 +22683,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/aks/eslz-cost-governance-with-kubecost", "service": "AKS", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Low", "text": "Use an external application such as kubecost to allocate costs to different users", @@ -22780,8 +22780,8 @@ "link": "https://learn.microsoft.com/azure/container-registry/", "service": "AKS", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use a private registry for your images, such as ACR", @@ -23060,9 +23060,9 @@ "link": "https://azure.github.io/application-gateway-kubernetes-ingress/setup/install-existing/", "service": "AKS", "services": [ - "ACR", "AppGW", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "If using AGIC, do not share an AppGW across clusters", @@ -23132,8 +23132,8 @@ "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", "service": "AKS", "services": [ - "VNet", "PrivateLink", + "VNet", "WAF" ], "severity": "Medium", @@ -23189,8 +23189,8 @@ "link": "https://learn.microsoft.com/azure/aks/internal-lb", "service": "AKS", "services": [ - "VNet", "AKS", + "VNet", "WAF" ], "severity": "Low", @@ -23284,8 +23284,8 @@ "link": "https://learn.microsoft.com/azure/aks/limit-egress-traffic", "service": "AKS", "services": [ - "NVA", - "WAF" + "WAF", + "NVA" ], "severity": "High", "text": "Filter egress traffic with AzFW/NVA if your security requirements mandate it", @@ -23387,9 +23387,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/ddos-protection-overview", "service": "AKS", "services": [ + "AKS", "VNet", "DDoS", - "AKS", "WAF" ], "severity": "Medium", @@ -23732,10 +23732,10 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance", "service": "AKS", "services": [ - "Monitor", + "WAF", "EventHubs", "Storage", - "WAF", + "Monitor", "ServiceBus" ], "severity": "Medium", @@ -23749,10 +23749,10 @@ "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", "service": "AKS", "services": [ - "NVA", - "LoadBalancer", "Monitor", - "WAF" + "LoadBalancer", + "WAF", + "NVA" ], "severity": "Medium", "text": "If not using egress filtering with AzFW/NVA, monitor standard ALB allocated SNAT ports", @@ -24073,9 +24073,9 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/monitoring#set-up-alerts", "service": "Azure OpenAI", "services": [ - "Subscriptions", - "AKV", "Monitor", + "AKV", + "Subscriptions", "WAF" ], "severity": "High", @@ -24290,8 +24290,8 @@ "link": "https://learn.microsoft.com/azure/architecture/ai-ml/architecture/baseline-openai-e2e-chat#azure-openai---reliability", "service": "Azure OpenAI", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Low", "text": "Deploy multiple OAI instances across regions", @@ -24345,8 +24345,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/business-continuity-disaster-recovery", "service": "Azure OpenAI", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Deploy separate fine tuned models across regions if finetuning is employed", @@ -24414,8 +24414,8 @@ "link": "https://learn.microsoft.com/azure/search/search-security-overview", "service": "Azure OpenAI", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Ensure TLS is enforced for data in transit across data sources, AI search used for Retrieval-Augmented Generation (RAG) and LLM communication", @@ -24455,8 +24455,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/ai-onboarding", "service": "Azure OpenAI", "services": [ - "Sentinel", "Monitor", + "Sentinel", "Defender", "WAF" ], @@ -24832,8 +24832,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs#base-series-and-codex-series-fine-tuned-models", "service": "Azure OpenAI", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Understand difference in cost of base models and fine tuned models and token step sizes", @@ -24846,8 +24846,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/latency#batching", "service": "Azure OpenAI", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "High", "text": "Batch requests, where possible, to minimize the per-call overhead which can reduce overall costs. Ensure you optimize batch size", @@ -24860,9 +24860,9 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs", "service": "Azure OpenAI", "services": [ - "Cost", "Monitor", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Set up a cost tracking system that monitors model usage and use that information to help inform model choices and prompt sizes", @@ -24902,8 +24902,8 @@ "link": "https://learn.microsoft.com/azure/machine-learning/prompt-flow/how-to-end-to-end-llmops-with-prompt-flow?view=azureml-api-2", "service": "Azure OpenAI", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Ensure deployment of Azure OpenAI instances across your various environments, such as development, test, and production supporting lrarning & experimentation. Apply LLMOps practices to automate the lifecycle management of your GenAI applications", @@ -25034,9 +25034,9 @@ "link": "https://github.com/Azure/aoai-apim/blob/main/README.md", "service": "Azure OpenAI", "services": [ - "ACR", - "WAF", "LoadBalancer", + "WAF", + "ACR", "APIM", "Entra" ], @@ -25148,8 +25148,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs", "service": "Azure OpenAI", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Develop your cost model, considering prompt sizes. Understanding prompt input and response sizes and how text translates into tokens helps you create a viable cost model", @@ -25162,8 +25162,8 @@ "link": "https://azure.microsoft.com/pricing/details/cognitive-services/openai-service/", "service": "Azure OpenAI", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Consider model pricing and capabilities when you choose models. Start with less-costly models for less-complex tasks like text generation or completion tasks and for complex tasks like language translation or content understanding, consider using more advanced models. Optimize costs while still achieving the desired application performance", @@ -25176,8 +25176,8 @@ "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs", "service": "Azure OpenAI", "services": [ - "Cost", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Maximize Azure OpenAI price breakpoints like fine-tuning and model breakpoints like image generation to your advantage. Fine-tuning is charged per hour, use as much time as you have available per hour to improve results without slipping into the next billing period. The cost for generating 100 images is the same as the cost for 1 image", @@ -25244,8 +25244,8 @@ "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", "service": "ACR", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Disable Azure Container Registry image export", @@ -25259,9 +25259,9 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", "service": "ACR", "services": [ - "ACR", "AzurePolicy", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Enable Azure Policies for Azure Container Registry", @@ -25275,9 +25275,9 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", "service": "ACR", "services": [ - "ACR", "AKV", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Sign and Verify containers with notation (Notary v2)", @@ -25292,9 +25292,9 @@ "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", "service": "ACR", "services": [ - "ACR", "AKV", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Encrypt registry with a customer managed key", @@ -25308,10 +25308,10 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", "service": "ACR", "services": [ - "ACR", "RBAC", "Entra", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Use Managed Identities to connect instead of Service Principals", @@ -25342,10 +25342,10 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", "service": "ACR", "services": [ - "ACR", "RBAC", "Entra", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", @@ -25388,10 +25388,10 @@ "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", "service": "ACR", "services": [ - "ACR", - "EventHubs", "PrivateLink", - "WAF" + "EventHubs", + "WAF", + "ACR" ], "severity": "High", "text": "Deploy images from a trusted environment", @@ -25405,10 +25405,10 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", "service": "ACR", "services": [ - "ACR", - "Entra", "AzurePolicy", - "WAF" + "Entra", + "WAF", + "ACR" ], "severity": "Medium", "text": "Disable Azure ARM audience tokens for authentication", @@ -25422,10 +25422,10 @@ "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", "service": "ACR", "services": [ - "ACR", "Monitor", "Entra", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Enable diagnostics logging", @@ -25439,8 +25439,8 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", "service": "ACR", "services": [ - "VNet", "PrivateLink", + "VNet", "Firewall", "WAF" ], @@ -25473,9 +25473,9 @@ "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", "service": "ACR", "services": [ - "ACR", "PrivateLink", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", @@ -25489,9 +25489,9 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", "service": "ACR", "services": [ - "ACR", "Defender", - "WAF" + "WAF", + "ACR" ], "severity": "Low", "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", @@ -25531,9 +25531,9 @@ "link": "https://learn.microsoft.com/azure/data-explorer/kusto/management/data-export/continuous-data-export", "service": "Azure Data Explorer", "services": [ - "Cost", "Storage", - "WAF" + "WAF", + "Cost" ], "text": "Leverage External Tables and Continuous data export overview to reduce costs", "waf": "Reliability" @@ -25574,8 +25574,8 @@ "service": "Azure Data Explorer", "services": [ "Storage", - "RBAC", - "WAF" + "WAF", + "RBAC" ], "text": "Replicate all management activities such as creating new tables or managing user roles on each cluster.", "waf": "Reliability" @@ -25600,8 +25600,8 @@ "link": "https://learn.microsoft.com/azure/data-explorer/business-continuity-overview#active-active-active-configuration", "service": "Azure Data Explorer", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "text": "For critical application with no tolerance for outages, create Active-Active-Active (always-on) configuration", "waf": "Reliability" @@ -25614,8 +25614,8 @@ "link": "https://learn.microsoft.com/azure/data-explorer/business-continuity-overview#active-active-configuration", "service": "Azure Data Explorer", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "text": "For critical applications, create Active-Active configuration in two paired regions", "waf": "Reliability" @@ -25641,11 +25641,11 @@ "link": "https://learn.microsoft.com/azure/data-explorer/business-continuity-overview#on-demand-data-recovery-configuration", "service": "Azure Data Explorer", "services": [ + "WAF", "Cost", - "ASR", + "AzurePolicy", "Storage", - "WAF", - "AzurePolicy" + "ASR" ], "text": "For applications, where cost is a concern and can withstand some downtime during failure, create on-demand data recovery cluster configuration", "waf": "Reliability" @@ -25924,11 +25924,11 @@ "guid": "eb710a37-cbc1-4055-8dd5-a936a8bb7cf5", "service": "AVS", "services": [ + "WAF", + "NetworkWatcher", "ExpressRoute", - "Monitor", "VPN", - "WAF", - "NetworkWatcher" + "Monitor" ], "severity": "High", "text": "Ensure ExpressRoute or VPN connections from on-premises to Azure are monitored using 'connection monitor'", @@ -25940,12 +25940,12 @@ "guid": "976e24f2-a7f8-426c-9253-2a92a2a7ed99", "service": "AVS", "services": [ - "ExpressRoute", "AVS", - "Monitor", "WAF", + "NetworkWatcher", "VM", - "NetworkWatcher" + "ExpressRoute", + "Monitor" ], "severity": "Medium", "text": "Ensure a connection monitor is created from an Azure native resource to an Azure VMware Solution virtual machine to monitor the Azure VMware Solution back-end ExpressRoute connection", @@ -25957,11 +25957,11 @@ "guid": "f41ce6a0-64f3-4805-bc65-3ab50df01265", "service": "AVS", "services": [ - "Monitor", "AVS", "WAF", + "NetworkWatcher", "VM", - "NetworkWatcher" + "Monitor" ], "severity": "Medium", "text": "Ensure a connection monitor is created from an on-premises resource to an Azure VMware Solution virtual machine to monitor end-2-end connectivity", @@ -26067,8 +26067,8 @@ "guid": "586cb291-ec16-4a1d-876e-f9f141acdce5", "service": "AVS", "services": [ - "VM", "AVS", + "VM", "Entra", "WAF" ], @@ -26094,9 +26094,9 @@ "guid": "a2adb1c3-d232-46af-825c-a44e1695fddd", "service": "AVS", "services": [ - "AppGW", "AVS", "Firewall", + "AppGW", "WAF" ], "severity": "High", @@ -26137,11 +26137,11 @@ "guid": "334fdf91-c234-4182-a652-75269440b4be", "service": "AVS", "services": [ - "ExpressRoute", + "DDoS", "WAF", + "ExpressRoute", "VPN", - "VNet", - "DDoS" + "VNet" ], "severity": "Medium", "text": "Is DDoS standard protection enabled on ExR/VPN Gateway subnet in Azure", @@ -26166,8 +26166,8 @@ "guid": "9ccbd869-266a-4cca-874f-aa19bf39d95d", "service": "AVS", "services": [ - "Defender", "AVS", + "Defender", "WAF" ], "severity": "Medium", @@ -26194,8 +26194,8 @@ "guid": "85e12139-bd7b-4b01-8f7b-95ef6e043e2a", "service": "AVS", "services": [ - "AVS", "SQL", + "AVS", "WAF" ], "severity": "Low", @@ -26298,9 +26298,9 @@ "guid": "4ba34d45-85e1-4213-abd7-bb012f7b95ef", "service": "AVS", "services": [ - "Cost", "AVS", - "WAF" + "WAF", + "Cost" ], "severity": "Medium", "text": "Ensure a good cost management process is in place for Azure VMware Solution - Azure Cost Management can be used", @@ -26312,9 +26312,9 @@ "guid": "6e043e2a-a359-4271-ae6e-205172676ae4", "service": "AVS", "services": [ - "Cost", "AVS", - "WAF" + "WAF", + "Cost" ], "severity": "Low", "text": "Are Azure reserved instances used to optimize cost for using Azure VMware Solution", @@ -26350,9 +26350,9 @@ "guid": "48b262d6-cc5f-4512-a253-98e6db9d37da", "service": "AVS", "services": [ - "Defender", - "VM", "AVS", + "VM", + "Defender", "WAF" ], "severity": "Medium", @@ -26365,8 +26365,8 @@ "guid": "41741583-3ef7-4ad7-a6d3-733165c7acbe", "service": "AVS", "services": [ - "Arc", "VM", + "Arc", "AVS", "WAF" ], @@ -26393,8 +26393,8 @@ "guid": "4ed90dae-2cc8-44c4-9b6b-781cbafe6c46", "service": "AVS", "services": [ - "VM", "Monitor", + "VM", "AVS", "WAF" ], @@ -26409,9 +26409,9 @@ "service": "AVS", "services": [ "AVS", - "Backup", "WAF", "VM", + "Backup", "AzurePolicy" ], "severity": "Medium", @@ -26424,9 +26424,9 @@ "guid": "ee29711b-d352-4caa-ab79-b198dab81932", "service": "AVS", "services": [ - "Defender", "Monitor", "AVS", + "Defender", "WAF" ], "severity": "Medium", @@ -26575,8 +26575,8 @@ "service": "AVS", "services": [ "Storage", - "VM", "AzurePolicy", + "VM", "WAF" ], "severity": "High", @@ -26657,8 +26657,8 @@ "service": "AVS", "services": [ "Monitor", - "AVS", "AzurePolicy", + "AVS", "WAF" ], "severity": "Medium", @@ -26671,8 +26671,8 @@ "guid": "aee3553a-fc83-4392-98b2-62d6cc5f5129", "service": "AVS", "services": [ - "Defender", "AVS", + "Defender", "WAF" ], "severity": "Medium", @@ -26760,10 +26760,10 @@ "guid": "d1d79a9b-2460-4448-aa8f-42d78e78cb6a", "service": "AVS", "services": [ - "NVA", "ExpressRoute", "AVS", - "WAF" + "WAF", + "NVA" ], "severity": "Medium", "text": "Will ExpressRoute Global Reach be used for connectivity between the primary and secondary Azure VMware Solution Private Clouds or is routing done through network virtual appliances?", @@ -26903,8 +26903,8 @@ "guid": "255461e2-aee3-4553-afc8-339248b262d6", "service": "AVS", "services": [ - "AKV", "ExpressRoute", + "AKV", "AVS", "WAF" ], @@ -27049,8 +27049,8 @@ "guid": "bc91a43d-90da-4e2c-a881-4706f7c1cbaf", "service": "AVS", "services": [ - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "If using a VPN connection for migrations, adjust your MTU size accordingly.", @@ -27103,9 +27103,9 @@ "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", "service": "AVS", "services": [ - "Storage", "ExpressRoute", - "WAF" + "WAF", + "Storage" ], "severity": "Medium", "text": "Ensure that a dedicated ExpressRoute Gateway is being used for external data storage solutions", @@ -27118,9 +27118,9 @@ "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", "service": "AVS", "services": [ - "Storage", "ExpressRoute", - "WAF" + "WAF", + "Storage" ], "severity": "Medium", "text": "Ensure that FastPath is enabled on the ExpressRoute Gateway that is being used for external data storage solutions", @@ -27234,11 +27234,11 @@ "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-shared-access-signature#shared-access-authorization-policies", "service": "Event Hubs", "services": [ - "AzurePolicy", - "EventHubs", - "RBAC", "TrafficManager", "WAF", + "RBAC", + "EventHubs", + "AzurePolicy", "Entra" ], "severity": "Medium", @@ -27254,12 +27254,12 @@ "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-managed-identity?tabs=latest", "service": "Event Hubs", "services": [ - "AKV", - "EventHubs", - "Storage", "WAF", + "EventHubs", "VM", - "Entra" + "Storage", + "Entra", + "AKV" ], "severity": "Medium", "text": "When possible, your application should be using a managed identity to authenticate to Azure Event Hub. If not, consider having the storage credential (SAS, service principal credential) in Azure Key Vault or an equivalent service", @@ -27291,10 +27291,10 @@ "link": "https://learn.microsoft.com/azure/event-hubs/monitor-event-hubs-reference", "service": "Event Hubs", "services": [ - "VNet", - "EventHubs", "Monitor", - "WAF" + "EventHubs", + "WAF", + "VNet" ], "severity": "Medium", "text": "Enable logging for security investigation. Use Azure Monitor to captured metrics and logs such as resource logs, runtime audit logs and Kafka logs", @@ -27309,10 +27309,10 @@ "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", "service": "Event Hubs", "services": [ - "VNet", "PrivateLink", "EventHubs", - "WAF" + "WAF", + "VNet" ], "severity": "Medium", "text": "Consider using private endpoints to access Azure Event Hub and disable public network access when applicable.", @@ -27356,9 +27356,9 @@ "link": "https://learn.microsoft.com/azure/event-hubs/event-hubs-premium-overview#high-availability-with-availability-zones", "service": "Event Hubs", "services": [ - "ACR", "EventHubs", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Leverage Availability Zones if regionally applicable", @@ -27538,8 +27538,8 @@ "link": "https://learn.microsoft.com/azure/service-fabric/how-to-managed-cluster-availability-zones", "service": "Azure Service Fabric", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Consider using Availability Zones for your Service Fabric clusters. Service Fabric managed cluster supports deployments that span across multiple Availability Zones to provide zone resiliency. This configuration will ensure high-availability of the critical system services and your applications to protect from single-points-of-failure.", @@ -27613,8 +27613,8 @@ "link": "https://learn.microsoft.com/azure/service-fabric/how-to-managed-cluster-networking#manage-nsg-rules", "service": "Azure Service Fabric", "services": [ - "VNet", "APIM", + "VNet", "WAF" ], "severity": "Medium", @@ -27628,11 +27628,11 @@ "link": "https://learn.microsoft.com/azure/service-fabric/service-fabric-best-practices-security#deploy-key-vault-certificates-to-service-fabric-cluster-virtual-machine-scale-sets", "service": "Azure Service Fabric", "services": [ - "AKV", - "Storage", "WAF", "VM", - "Entra" + "Storage", + "Entra", + "AKV" ], "severity": "Medium", "text": "Deploy Key Vault certificates to Service Fabric cluster virtual machine scale sets. Centralizing storage of application secrets in Azure Key Vault allows you to control their distribution. Key Vault greatly reduces the chances that secrets may be accidentally leaked.", @@ -27656,8 +27656,8 @@ "link": "https://learn.microsoft.com/azure/service-fabric/service-fabric-resource-governance#resource-governance-mechanism", "service": "Azure Service Fabric", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use resource requests and limits to govern resource usage across the nodes in your cluster. Enforcing resource limits helps ensure that one service doesn't consume too many resources and starve other services.", @@ -27733,8 +27733,8 @@ "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", "service": "Spring Apps", "services": [ - "FrontDoor", "TrafficManager", + "FrontDoor", "WAF" ], "severity": "Medium", @@ -27748,8 +27748,8 @@ "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", "service": "Spring Apps", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "In supported region, Azure Spring Apps can be deployed as zone redundant, which means that instances are automatically distributed across availability zones. This feature is only available in Standard and Enterprise tiers.", @@ -27861,12 +27861,12 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", "service": "Service Bus", "services": [ - "AzurePolicy", - "RBAC", "TrafficManager", "WAF", - "ServiceBus", - "Entra" + "RBAC", + "AzurePolicy", + "Entra", + "ServiceBus" ], "severity": "Medium", "text": "Avoid using root account when it is not necessary", @@ -27900,8 +27900,8 @@ "service": "Service Bus", "services": [ "WAF", - "Storage", "RBAC", + "Storage", "Subscriptions", "ServiceBus" ], @@ -27918,9 +27918,9 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", "service": "Service Bus", "services": [ - "ServiceBus", - "VNet", "Monitor", + "VNet", + "ServiceBus", "WAF" ], "severity": "Medium", @@ -27936,9 +27936,9 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", "service": "Service Bus", "services": [ + "PrivateLink", "VNet", "ServiceBus", - "PrivateLink", "WAF" ], "severity": "Medium", @@ -27969,8 +27969,8 @@ "guid": "32d41e36-11c8-417b-8afb-c410d4391898", "service": "Azure Synapse Analytics", "services": [ - "Entra", "SQL", + "Entra", "WAF" ], "severity": "High", @@ -27999,8 +27999,8 @@ "guid": "ec823923-7a15-42d6-ac5e-402925388e5d", "service": "Azure Synapse Analytics", "services": [ - "Entra", "AzurePolicy", + "Entra", "WAF" ], "severity": "High", @@ -28016,9 +28016,9 @@ "service": "Azure Synapse Analytics", "services": [ "Storage", - "RBAC", "Monitor", - "WAF" + "WAF", + "RBAC" ], "severity": "Medium", "text": "Use Azure RBAC to control access on storage and Synapse RBAC to control access on workspace level depending on the personas of the team to fine grain the access on data and compute", @@ -28154,6 +28154,21 @@ "text": "Store passwords, secerts and keys in Azure key vault", "waf": "Security" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "description": "You can store credentials or secret values in an Azure Key Vault and use them during pipeline execution to pass to your activities.", + "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "services": [ + "AKV", + "WAF" + ], + "severity": "Medium", + "text": "Use Azure Key Vault secrets in pipeline activities", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "WAF checklist", @@ -28190,14 +28205,26 @@ "guid": "4350d092-d234-4292-a752-8537a551c5bf", "service": "Azure Data Factory", "services": [ - "Entra", "AzurePolicy", + "Entra", "WAF" ], "severity": "High", "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Security" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "service": "Azure Data Factory", + "services": [ + "WAF" + ], + "severity": "Medium", + "text": "Disable access over public internet and configure either firewall rules or trusted services rules", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "WAF checklist", @@ -28235,15 +28262,31 @@ "link": "https://learn.microsoft.com/azure/data-factory/managed-virtual-network-private-endpoint#managed-private-endpoints", "service": "Azure Data Factory", "services": [ - "VNet", "PrivateLink", "EventHubs", - "WAF" + "WAF", + "VNet" ], "severity": "Medium", "text": "Configure managed private endpoints to connect to resources using managed azure IR", "waf": "Security" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "description": "By using Azure Private Link, you can connect to various platform as a service (PaaS) deployments in Azure via a private endpoint. A private endpoint is a private IP address within a specific virtual network and subnet", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", + "services": [ + "PrivateLink", + "VNet", + "WAF" + ], + "severity": "Medium", + "text": "Configure Private Links to connect to sources in customer Vnet and data factory", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "WAF checklist", @@ -28301,6 +28344,35 @@ "text": "Store passwords, secrets in Azure Key Vault", "waf": "Security" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "description": "You can store credentials or secret values in an Azure Key Vault and use them during pipeline execution to pass to your activities.", + "guid": "6f4a1652-bddd-4ea8-a487-cdec4861bc3b", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "services": [ + "AKV", + "WAF" + ], + "severity": "Medium", + "text": "Use Azure Key Vault secrets in pipeline activities", + "waf": "Security" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "description": "You can encrypt and store credentials for any of your on-premises data stores (linked services with sensitive information) on a machine with self-hosted integration runtime.", + "guid": "c14aeb7e-66e8-4d9a-9bec-218e6436b173", + "link": "https://learn.microsoft.com/azure/data-factory/encrypt-credentials-self-hosted-integration-runtime", + "service": "Azure Data Factory", + "services": [ + "WAF" + ], + "severity": "Medium", + "text": "Encrypt credentials for on-premises using SHIR data stores in Azure Data Factory", + "waf": "Security" + }, { "checklist": "WAF checklist", "guid": "6db55f57-9603-4334-adf9-cc23418db612", @@ -28320,8 +28392,8 @@ "link": "https://learn.microsoft.com/azure/role-based-access-control/best-practices", "service": "Microsoft Purview", "services": [ - "Subscriptions", "RBAC", + "Subscriptions", "WAF" ], "severity": "Medium", @@ -28434,9 +28506,9 @@ "link": "https://learn.microsoft.com/purview/concept-best-practices-security#use-network-security-groups", "service": "Microsoft Purview", "services": [ + "PrivateLink", "VNet", "VM", - "PrivateLink", "WAF" ], "severity": "Medium", @@ -28449,10 +28521,10 @@ "link": "https://learn.microsoft.com/azure/firewall/overview", "service": "Microsoft Purview", "services": [ - "NVA", "PrivateLink", "Firewall", - "WAF" + "WAF", + "NVA" ], "severity": "Medium", "text": "Implement Microsoft Purview with private endpoints managed by a Network Virtual Appliance, such as�Azure Firewall�for network inspection and network filtering. (Microsoft Purview Data Map)", @@ -28465,8 +28537,8 @@ "link": "https://learn.microsoft.com/purview/concept-best-practices-network", "service": "Microsoft Purview", "services": [ - "VNet", "PrivateLink", + "VNet", "WAF" ], "severity": "Medium", @@ -28519,8 +28591,8 @@ "service": "Microsoft Purview", "services": [ "Storage", - "RBAC", - "WAF" + "WAF", + "RBAC" ], "severity": "Medium", "text": "Use Azure RBACs to restrict the access of your storage account (not managed by MS) only to intended users.", @@ -28621,8 +28693,8 @@ "link": "https://learn.microsoft.com/azure/databricks/security/auth/#single-sign-on", "service": "Azure Databricks", "services": [ - "Entra", "AzurePolicy", + "Entra", "WAF" ], "severity": "High", @@ -28679,16 +28751,31 @@ "guid": "11cc57b4-a4b1-4410-b43a-58a9c2289b3d", "service": "Azure Databricks", "services": [ + "WAF", "EventHubs", + "AzurePolicy", "Storage", - "SQL", - "WAF", - "AzurePolicy" + "SQL" ], "severity": "Medium", "text": "Limit cluster creation rights.", "waf": "Security" }, + { + "arm-service": "Microsoft.Databricks/workspaces", + "checklist": "WAF checklist", + "description": "Account admins can configure a workspace setting called RestrictWorkspaceAdmins to restrict workspace admins to only change a job owner to themselves and the job run as setting to a service principal that they have the Service Principal User role on.", + "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", + "services": [ + "RBAC", + "WAF" + ], + "severity": "High", + "text": "Restrict workspace admins", + "waf": "Security" + }, { "arm-service": "Microsoft.Databricks/workspaces", "checklist": "WAF checklist", @@ -28770,11 +28857,11 @@ "link": "https://learn.microsoft.com/azure/databricks/security/keys/customer-managed-keys", "service": "Azure Databricks", "services": [ - "AKV", + "WAF", "Backup", "Storage", "SQL", - "WAF" + "AKV" ], "severity": "Medium", "text": "Add a customer-managed key for managed services and workspace storage", @@ -28788,8 +28875,8 @@ "link": "https://learn.microsoft.com/azure/databricks/security/network/front-end/ip-access-list", "service": "Azure Databricks", "services": [ - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "Enable IP access lists to restrict access to certain IP addresses.", @@ -28919,12 +29006,12 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "App Gateway", "services": [ - "NVA", - "WAF", - "Subscriptions", "AppGW", + "WAF", + "NVA", + "Entra", "VNet", - "Entra" + "Subscriptions" ], "severity": "Medium", "text": "Deploy Azure Application Gateway v2 or partner NVAs used for proxying inbound HTTP(S) connections within the landing-zone virtual network and with the apps that they're securing.", @@ -28969,9 +29056,9 @@ "link": "https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2", "service": "App Gateway", "services": [ - "ACR", "AppGW", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Deploy Application Gateway across Availability Zones", @@ -28985,10 +29072,10 @@ "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "service": "Front Door", "services": [ - "AppGW", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Medium", "text": "When using Front Door and Application Gateway to help protect HTTP/S apps, use WAF policies in Front Door. Lock down Application Gateway to receive traffic only from Front Door.", @@ -29081,8 +29168,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", "service": "App Gateway", "services": [ - "AppGW", "AzurePolicy", + "AppGW", "WAF" ], "severity": "High", @@ -29112,8 +29199,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/policy-overview?source=recommendations", "service": "App Gateway", "services": [ - "AppGW", "AzurePolicy", + "AppGW", "WAF" ], "severity": "High", @@ -29253,9 +29340,9 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-secured-hub-app-gateway", "service": "App Gateway", "services": [ - "ExpressRoute", - "WAF", "AppGW", + "WAF", + "ExpressRoute", "VPN", "VNet" ], @@ -29497,8 +29584,8 @@ "service": "Key Vault", "services": [ "AKV", - "Backup", - "WAF" + "WAF", + "Backup" ], "severity": "High", "text": "Familiarize yourself with the Key Vault's best practices such as isolation recommendations, access control, data protection, backup, and logging.", @@ -29511,9 +29598,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", "service": "Key Vault", "services": [ - "ACR", "AKV", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Key Vault is a managed service and Microsoft will handle the failover within and across region. Familiarize yourself with the Key Vault's availability and redundancy.", @@ -29540,8 +29627,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance#failover-across-regions", "service": "Key Vault", "services": [ - "AKV", "AzurePolicy", + "AKV", "WAF" ], "severity": "Medium", @@ -29556,10 +29643,10 @@ "service": "Key Vault", "services": [ "WAF", - "AKV", "Backup", "Storage", - "Subscriptions" + "Subscriptions", + "AKV" ], "severity": "Medium", "text": "When you back up a key vault object, such as a secret, key, or certificate, the backup operation will download the object as an encrypted blob. This blob can't be decrypted outside of Azure. To get usable data from this blob, you must restore the blob into a key vault within the same Azure subscription and Azure geography. Familiarize yourself with the Key Vault's backup and restore guidance.", @@ -29601,8 +29688,8 @@ "service": "Key Vault", "services": [ "AKV", - "Backup", - "WAF" + "WAF", + "Backup" ], "severity": "Low", "text": "Understand Key Vault's backup limitations. Key Vault does not support the ability to backup more than 500 past versions of a key, secret, or certificate object. Attempting to backup a key, secret, or certificate object may result in an error. It is not possible to delete previous versions of a key, secret, or certificate.", @@ -29616,8 +29703,8 @@ "service": "Key Vault", "services": [ "AKV", - "Backup", - "WAF" + "WAF", + "Backup" ], "severity": "Low", "text": "Key Vault doesn't currently provide a way to back up an entire key vault in a single operation and keys, secrets and certitificates must be backup indvidually. Familiarize yourself with the Key Vault's backup and restore guidance.", @@ -29630,8 +29717,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview#purge-protection", "service": "Key Vault", "services": [ - "AKV", "EventHubs", + "AKV", "WAF" ], "severity": "Medium", @@ -29646,8 +29733,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/rbac-guide?tabs=azure-cli", "service": "Key Vault", "services": [ - "AKV", "RBAC", + "AKV", "WAF" ], "severity": "Medium", @@ -29729,10 +29816,10 @@ "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", "service": "Entra", "services": [ - "ACR", - "Subscriptions", "RBAC", - "WAF" + "Subscriptions", + "WAF", + "ACR" ], "severity": "High", "text": "Enforce a RBAC model that aligns to your cloud operating model. Scope and Assign across Management Groups and Subscriptions.", @@ -29772,8 +29859,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", "service": "Entra", "services": [ - "Entra", "AzurePolicy", + "Entra", "WAF" ], "severity": "High", @@ -29918,14 +30005,14 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology", "service": "VNet", "services": [ - "VNet", - "ExpressRoute", + "DNS", + "WAF", "NVA", - "Firewall", + "ExpressRoute", + "Entra", "VPN", - "WAF", - "DNS", - "Entra" + "VNet", + "Firewall" ], "severity": "High", "text": "Deploy shared networking services, including ExpressRoute gateways, VPN gateways, and Azure Firewall or partner NVAs in the central-hub virtual network. If necessary, also deploy DNS services.", @@ -29954,8 +30041,8 @@ "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", "service": "NVA", "services": [ - "NVA", - "WAF" + "WAF", + "NVA" ], "severity": "Medium", "text": "When deploying partner networking technologies or NVAs, follow the partner vendor's guidance.", @@ -29970,8 +30057,8 @@ "services": [ "ExpressRoute", "ARS", - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Low", "text": "If you need transit between ExpressRoute and VPN gateways in hub and spoke scenarios, use Azure Route Server.", @@ -29986,8 +30073,8 @@ "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", "service": "ARS", "services": [ - "VNet", "ARS", + "VNet", "WAF" ], "severity": "Low", @@ -30002,9 +30089,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", "service": "VNet", "services": [ - "ACR", "VNet", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "For network architectures with multiple hub-and-spoke topologies across Azure regions, use global virtual network peerings between the hub VNets to connect the regions to each other.", @@ -30034,8 +30121,8 @@ "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", "service": "VNet", "services": [ - "VNet", "ExpressRoute", + "VNet", "WAF" ], "severity": "Medium", @@ -30126,8 +30213,8 @@ "service": "ExpressRoute", "services": [ "ExpressRoute", - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "For scenarios where MACsec isn't an option (for example, not using ExpressRoute Direct), use a VPN gateway to establish IPsec tunnels over ExpressRoute private peering.", @@ -30141,8 +30228,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "service": "ExpressRoute", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Ensure no overlapping IP address spaces across Azure regions and on-premises locations are used.", @@ -30202,8 +30289,8 @@ "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone", "service": "Public IP Addresses", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. ", @@ -30232,9 +30319,9 @@ "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", "service": "DNS", "services": [ - "ACR", "DNS", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "For environments where name resolution across Azure and on-premises is required and there is no existing enterprise DNS service like Active Directory, use Azure DNS Private Resolver to route DNS requests to Azure or to on-premises DNS servers.", @@ -30295,8 +30382,8 @@ "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", "service": "Bastion", "services": [ - "Bastion", - "WAF" + "WAF", + "Bastion" ], "severity": "Medium", "text": "Use Azure Bastion to securely connect to your network.", @@ -30312,8 +30399,8 @@ "service": "Bastion", "services": [ "VNet", - "Bastion", - "WAF" + "WAF", + "Bastion" ], "severity": "Medium", "text": "Use Azure Bastion in a subnet /26 or larger.", @@ -30327,10 +30414,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "service": "WAF", "services": [ - "ACR", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Azure Front Door and WAF policies to provide global protection across Azure regions for inbound HTTP/S connections to a landing zone.", @@ -30344,10 +30431,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "WAF", "services": [ - "AppGW", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Low", "text": "When using Azure Front Door and Azure Application Gateway to help protect HTTP/S apps, use WAF policies in Azure Front Door. Lock down Azure Application Gateway to receive traffic only from Azure Front Door.", @@ -30421,8 +30508,8 @@ "link": "https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies#corp", "service": "Policy", "services": [ - "VM", "AzurePolicy", + "VM", "WAF" ], "severity": "High", @@ -30437,10 +30524,10 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", "service": "ExpressRoute", "services": [ - "Backup", "ExpressRoute", - "VPN", - "WAF" + "Backup", + "WAF", + "VPN" ], "severity": "Medium", "text": "Use ExpressRoute as the primary connection to Azure. Use VPNs as a source of backup connectivity.", @@ -30472,8 +30559,8 @@ "service": "ExpressRoute", "services": [ "ExpressRoute", - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements.", @@ -30488,9 +30575,9 @@ "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", "service": "ExpressRoute", "services": [ - "Cost", "ExpressRoute", - "WAF" + "WAF", + "Cost" ], "severity": "High", "text": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost.", @@ -30505,9 +30592,9 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", "service": "ExpressRoute", "services": [ - "Cost", "ExpressRoute", - "WAF" + "WAF", + "Cost" ], "severity": "High", "text": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU.", @@ -30568,8 +30655,8 @@ "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", "service": "VPN", "services": [ - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available).", @@ -30583,8 +30670,8 @@ "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", "service": "VPN", "services": [ - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "Use redundant VPN appliances on-premises (active/active or active/passive).", @@ -30598,9 +30685,9 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "service": "ExpressRoute", "services": [ - "Cost", "ExpressRoute", - "WAF" + "WAF", + "Cost" ], "severity": "High", "text": "If using ExpressRoute Direct, consider using ExpressRoute Local circuits to the local Azure regions to save costs.", @@ -30645,10 +30732,10 @@ "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", "service": "ExpressRoute", "services": [ - "ACR", "Monitor", "NetworkWatcher", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Connection Monitor for connectivity monitoring across the network, especially between on-premises and Azure.", @@ -30679,8 +30766,8 @@ "service": "ExpressRoute", "services": [ "ExpressRoute", - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "Use site-to-site VPN as failover of ExpressRoute, if only using a single ExpressRoute circuit.", @@ -30710,9 +30797,9 @@ "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", "service": "ExpressRoute", "services": [ - "ACR", "ExpressRoute", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "If using ExpressRoute, your on-premises routing should be dynamic: in the event of a connection failure it should converge to the remaining connection of the circuit. Load should be shared across both connections ideally as active/active, although active/passive is supported too.", @@ -30770,8 +30857,8 @@ "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-howto-setup-alerts-virtual-network-gateway-log", "service": "ExpressRoute", "services": [ - "VNet", "ExpressRoute", + "VNet", "Monitor", "WAF" ], @@ -30787,8 +30874,8 @@ "link": "https://learn.microsoft.com/azure/expressroute/virtual-network-connectivity-guidance", "service": "ExpressRoute", "services": [ - "VNet", "ExpressRoute", + "VNet", "WAF" ], "severity": "Medium", @@ -30802,8 +30889,8 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", "service": "N/A", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Low", "text": "Do not send Azure traffic to hybrid locations for inspection. Instead, follow the principle 'traffic in Azure stays in Azure' so that communication across resources in Azure occurs via the Microsoft backbone network.", @@ -30831,11 +30918,11 @@ "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", "service": "Firewall", "services": [ + "WAF", "ACR", - "Firewall", "RBAC", - "WAF", - "AzurePolicy" + "AzurePolicy", + "Firewall" ], "severity": "Medium", "text": "Create a global Azure Firewall policy to govern security posture across the global network environment and assign it to all Azure Firewall instances. Allow for granular policies to meet requirements of specific regions by delegating incremental firewall policies to local security teams via Azure role-based access control.", @@ -30929,12 +31016,12 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", "service": "Firewall", "services": [ - "VNet", + "WAF", "NVA", - "Firewall", "VWAN", "Storage", - "WAF" + "VNet", + "Firewall" ], "severity": "High", "text": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance.", @@ -30963,8 +31050,8 @@ "link": "https://learn.microsoft.com/azure/firewall-manager/migrate-to-policy", "service": "Firewall", "services": [ - "Firewall", "AzurePolicy", + "Firewall", "WAF" ], "severity": "High", @@ -31113,8 +31200,8 @@ "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", "service": "Firewall", "services": [ - "Firewall", "Monitor", + "Firewall", "WAF" ], "severity": "High", @@ -31145,9 +31232,9 @@ "link": "https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell", "service": "Firewall", "services": [ - "ACR", "Firewall", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance.", @@ -31193,9 +31280,9 @@ "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview", "service": "ExpressRoute", "services": [ - "PrivateLink", "ExpressRoute", - "WAF" + "WAF", + "PrivateLink" ], "severity": "Medium", "text": "Access Azure PaaS services from on-premises via private endpoints and ExpressRoute private peering. This method avoids transiting over the public internet.", @@ -31225,11 +31312,11 @@ "link": "azure/private-link/inspect-traffic-with-azure-firewall", "service": "Firewall", "services": [ - "NVA", - "Firewall", - "WAF", "PrivateLink", - "DNS" + "DNS", + "WAF", + "NVA", + "Firewall" ], "severity": "Medium", "text": "Filter egress traffic to Azure PaaS services using FQDNs instead of IP addresses in Azure Firewall or an NVA to prevent data exfiltration. If using Private Link you can block all FQDNs, otherwise allow only the required PaaS services.", @@ -31244,10 +31331,10 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", "service": "ExpressRoute", "services": [ - "VNet", "ExpressRoute", - "VPN", - "WAF" + "VNet", + "WAF", + "VPN" ], "severity": "High", "text": "Use at least a /27 prefix for your Gateway subnets.", @@ -31276,9 +31363,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", "service": "NSG", "services": [ - "ACR", "VNet", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones).", @@ -31292,10 +31379,10 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "service": "NSG", "services": [ - "NVA", "VNet", "Entra", - "WAF" + "WAF", + "NVA" ], "severity": "Medium", "text": "Use NSGs and application security groups to micro-segment traffic within the landing zone and avoid using a central NVA to filter traffic flows.", @@ -31310,8 +31397,8 @@ "link": "https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview", "service": "NSG", "services": [ - "VNet", "NetworkWatcher", + "VNet", "WAF" ], "severity": "Medium", @@ -31357,9 +31444,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/virtual-wan-network-topology#virtual-wan-network-design-recommendationst", "service": "VWAN", "services": [ - "ACR", "VWAN", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use a Virtual WAN hub per Azure region to connect multiple landing zones together across Azure regions via a common global Azure Virtual WAN.", @@ -31404,8 +31491,8 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", "service": "VWAN", "services": [ - "VWAN", "Monitor", + "VWAN", "WAF" ], "severity": "Medium", @@ -31438,8 +31525,8 @@ "service": "VWAN", "services": [ "ExpressRoute", - "VPN", - "WAF" + "WAF", + "VPN" ], "severity": "Medium", "text": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN.", @@ -31514,8 +31601,8 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "service": "Policy", "services": [ - "Subscriptions", "AzurePolicy", + "Subscriptions", "WAF" ], "severity": "Medium", @@ -31545,8 +31632,8 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", "service": "Policy", "services": [ - "Subscriptions", "AzurePolicy", + "Subscriptions", "WAF" ], "severity": "Low", @@ -31577,11 +31664,11 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", "service": "Policy", "services": [ - "AzurePolicy", "WAF", "RBAC", - "Subscriptions", - "Entra" + "AzurePolicy", + "Entra", + "Subscriptions" ], "severity": "Medium", "text": "Assign the built-in Resource Policy Contributor role at a particular scope to enable application-level governance.", @@ -31595,8 +31682,8 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "service": "Policy", "services": [ - "Subscriptions", "AzurePolicy", + "Subscriptions", "WAF" ], "severity": "Medium", @@ -31626,8 +31713,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/sovereign-landing-zone", "service": "Policy", "services": [ - "Subscriptions", "AzurePolicy", + "Subscriptions", "WAF" ], "severity": "Medium", @@ -31669,11 +31756,11 @@ "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/logs/workspace-design#azure-regions", "service": "Monitor", "services": [ - "AzurePolicy", - "Monitor", - "RBAC", "WAF", - "Entra" + "RBAC", + "AzurePolicy", + "Entra", + "Monitor" ], "severity": "Medium", "text": "Use a single monitor logs workspace to manage platforms centrally except where Azure role-based access control (Azure RBAC), data sovereignty requirements, or data retention policies mandate separate workspaces.", @@ -31719,9 +31806,9 @@ "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", "service": "VM", "services": [ - "VM", "Monitor", "AzurePolicy", + "VM", "WAF" ], "severity": "Medium", @@ -31842,8 +31929,8 @@ "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", "service": "VM", "services": [ - "VM", "AzurePolicy", + "VM", "WAF" ], "severity": "Medium", @@ -31858,9 +31945,9 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", "service": "VM", "services": [ - "VM", "Monitor", "AzurePolicy", + "VM", "WAF" ], "severity": "Medium", @@ -31875,10 +31962,10 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "service": "VM", "services": [ - "ACR", - "VM", "ASR", - "WAF" + "VM", + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Azure Site Recovery for Azure-to-Azure Virtual Machines disaster recovery scenarios. This enables you to replicate workloads across regions.", @@ -31907,9 +31994,9 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "service": "WAF", "services": [ - "AppGW", "FrontDoor", - "WAF" + "WAF", + "AppGW" ], "severity": "High", "text": "Add diagnostic settings to save WAF logs from application delivery services like Azure Front Door and Azure Application Gateway. Regularly review the logs to check for attacks and for false positive detections.", @@ -31924,9 +32011,9 @@ "service": "WAF", "services": [ "Sentinel", - "AppGW", "FrontDoor", - "WAF" + "WAF", + "AppGW" ], "severity": "Medium", "text": "Send WAF logs from your application delivery services like Azure Front Door and Azure Application Gateway to Microsoft Sentinel. Detect attacks and integrate WAF telemetry into your overall Azure environment.", @@ -31971,8 +32058,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "AKV", "AzurePolicy", + "AKV", "WAF" ], "severity": "Medium", @@ -31987,8 +32074,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "AKV", "RBAC", + "AKV", "Entra", "WAF" ], @@ -32032,9 +32119,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "AKV", "PrivateLink", "VNet", + "AKV", "WAF" ], "severity": "Medium", @@ -32049,8 +32136,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", "service": "Key Vault", "services": [ - "AKV", "Monitor", + "AKV", "Entra", "WAF" ], @@ -32066,8 +32153,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "AKV", "AzurePolicy", + "AKV", "WAF" ], "severity": "Medium", @@ -32097,10 +32184,10 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "ACR", "ASR", "AKV", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "If you want to bring your own keys, this might not be supported across all considered services. Implement relevant mitigation so that inconsistencies don't hinder desired outcomes. Choose appropriate region pairs and disaster recovery regions that minimize latency.", @@ -32142,8 +32229,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", "service": "Defender", "services": [ - "Defender", "Subscriptions", + "Defender", "WAF" ], "severity": "High", @@ -32157,8 +32244,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", "service": "Defender", "services": [ - "Defender", "Subscriptions", + "Defender", "WAF" ], "severity": "High", @@ -32172,8 +32259,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/connect-azure-subscription", "service": "Defender", "services": [ - "Defender", "Subscriptions", + "Defender", "WAF" ], "severity": "High", @@ -32202,8 +32289,8 @@ "link": "https://learn.microsoft.com/azure/security-center/", "service": "VM", "services": [ - "Defender", "Monitor", + "Defender", "WAF" ], "severity": "Medium", @@ -32234,9 +32321,9 @@ "link": "https://learn.microsoft.com/en-us/azure/well-architected/security/monitor-threats#centralized-threat-detection-with-correlated-logs", "service": "Entra", "services": [ - "ACR", "Entra", - "WAF" + "WAF", + "ACR" ], "severity": "High", "text": "Centralized threat detection with correlated logs - consolidate security data in a central location where it can be correlated across various services via SIEM (security information and event management)", @@ -32444,9 +32531,9 @@ "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", "service": "APIM", "services": [ - "ACR", "AzurePolicy", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Use Policy Fragments to avoid repeating same policies definitions across multiple APIs", @@ -32595,8 +32682,8 @@ "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", "service": "APIM", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "For DR, leverage the premium tier with deployments scaled across two or more regions for 99.99% SLA", @@ -32775,10 +32862,10 @@ "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", "service": "APIM", "services": [ - "FrontDoor", "APIM", - "Entra", - "WAF" + "FrontDoor", + "WAF", + "Entra" ], "severity": "Medium", "text": "Use Azure Front Door in front of APIM for multi-region deployment", @@ -32805,11 +32892,11 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", "service": "APIM", "services": [ - "Monitor", "WAF", - "VNet", "APIM", - "Entra" + "Entra", + "Monitor", + "VNet" ], "severity": "Medium", "text": "Deploy network security groups (NSG) to your subnets to restrict or monitor traffic to/from APIM.", @@ -32822,11 +32909,11 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", "service": "APIM", "services": [ - "WAF", - "VNet", "PrivateLink", + "WAF", "APIM", - "Entra" + "Entra", + "VNet" ], "severity": "Medium", "text": "Deploy Private Endpoints to filter incoming traffic when APIM is not deployed to a VNet.", @@ -33001,10 +33088,10 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", "service": "APIM", "services": [ - "AppGW", "APIM", - "Entra", - "WAF" + "AppGW", + "WAF", + "Entra" ], "severity": "High", "text": "Use web application firewall (WAF) by deploying Application Gateway in front of APIM", @@ -33057,8 +33144,8 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/high-availability#multiple-write-regions", "service": "CosmosDB", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Leverage Multi-Region Writes", @@ -33072,8 +33159,8 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/high-availability#slas", "service": "CosmosDB", "services": [ - "ACR", - "WAF" + "WAF", + "ACR" ], "severity": "Medium", "text": "Distribute your data globally", @@ -33117,8 +33204,8 @@ "service": "CosmosDB", "services": [ "Storage", - "Backup", "CosmosDB", + "Backup", "WAF" ], "severity": "Medium", @@ -33150,9 +33237,9 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/continuous-backup-restore-introduction", "service": "CosmosDB", "services": [ - "Backup", "CosmosDB", - "WAF" + "WAF", + "Backup" ], "severity": "Medium", "text": "Continous Backup with point-in-time restore in Azure Cosmos DB", @@ -33251,6 +33338,147 @@ "text": "If deploying to an Isolated environment, use or migrate to App Service Environment (ASE) v3", "waf": "Reliability" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "65285269-440c-44be-9d3e-0844276d4bdc", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/pass-foudations-playbooks-ADB_v1.docx", + "service": "Azure Data Factory", + "services": [ + "WAF" + ], + "severity": "High", + "text": "Reference Databricks HA/DR playbook", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "a0e6c465-89d5-458b-a37d-3974d1112dbd", + "link": "https://github.com/databrickslabs/databricks-sync", + "service": "Azure Data Factory", + "services": [ + "WAF" + ], + "severity": "Low", + "text": "Use Databricks Sync", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "89d558b9-37d3-4974-b111-2dbd7aaf12e6", + "link": "https://learn.microsoft.com/azure/databricks/security/secrets/secret-scopes", + "service": "Azure Data Factory", + "services": [ + "Backup", + "WAF" + ], + "severity": "Medium", + "text": "Backup your workspace configuration including ARM templates and secret scopes", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "b94ee5ef-47d2-4d92-a81b-1cd6d1f54b29", + "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/sharing-metadata-across-different-databricks-workspaces-using/ba-p/3679757", + "service": "Azure Data Factory", + "services": [ + "WAF", + "ACR" + ], + "severity": "Medium", + "text": "Share metaData across different Databricks workspaces using Hive external metastore", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "769e3969-0e78-428a-a936-657d03b0f466", + "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/disaster-recovery-strategy-in-azure-databricks-using-the-hive/ba-p/3684581", + "service": "Azure Data Factory", + "services": [ + "ASR", + "WAF" + ], + "severity": "Medium", + "text": "Plan Disaster Recovery strategy in Databricks using the Hive External Metastore", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "4b1d944a-3598-437e-b79d-6c6d3a364a5b", + "link": "https://www.databricks.com/blog/2021/04/20/attack-of-the-delta-clones-against-disaster-recovery-availability-complexity.html", + "service": "Azure Data Factory", + "services": [ + "Backup", + "WAF" + ], + "severity": "Medium", + "text": "Backup your data with deep and shallow clones", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "description": "Download the blob using the secondary endpoint in RAGRS storage account", + "guid": "7abae48a-bd54-4cd7-ae2e-86768357c559", + "link": "https://techcommunity.microsoft.com/t5/azure-paas-blog/download-the-blob-using-secondary-endpoint-in-ragrs-storage/ba-p/2403750", + "service": "Azure Data Factory", + "services": [ + "Storage", + "Backup", + "WAF" + ], + "severity": "Medium", + "text": "Backup your data to Azure Storage RA-GRS", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "675c5ee8-5b85-49c7-944c-e3b1a28b875a", + "link": "https://learn.microsoft.com/azure/databricks/dev-tools/index-ci-cd", + "service": "Azure Data Factory", + "services": [ + "Backup", + "WAF" + ], + "severity": "High", + "text": "Backup your code with DevOps", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "guid": "a1bf1038-9f03-4a4d-8ce4-63dbbbc8682a", + "link": "https://learn.microsoft.com/azure/databricks/administration-guide/disaster-recovery", + "service": "Azure Data Factory", + "services": [ + "ASR", + "WAF" + ], + "severity": "High", + "text": "Plan for Disaster recovery using Active/Active or Active/Passive Configuration", + "waf": "Reliability" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "WAF checklist", + "description": "Migration package to log all Databricks resources for backup and/or migrating to another Databricks workspace", + "guid": "5abc92a4-eda1-4dae-8cc8-5c47c6b781cc", + "link": "https://github.com/databrickslabs/migrate", + "service": "Azure Data Factory", + "services": [ + "Backup", + "WAF" + ], + "severity": "Medium", + "text": "Use Databricks Migration tools", + "waf": "Reliability" + }, { "checklist": "WAF checklist", "guid": "bb235c70-5e17-496f-bedf-a8a4c8cdec4c", @@ -33368,6 +33596,7 @@ "description": "Azure Event Hub provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", "guid": "7aaf12e7-b94e-4f6e-847d-2d92981b1cd6", "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend SkuName = tostring(sku.name) | extend EncryptionEnabled = iif(isnotempty(properties.encryption.keySource), 'Enabled', 'Disabled') | extend compliant = iif(EncryptionEnabled == 'Enabled', true, false) | project name, resourceGroup, location, SkuName, EncryptionEnabled, compliant | where SkuName == 'Premium'", "service": "Event Hubs", "services": [ "EventHubs" @@ -33384,6 +33613,7 @@ "description": "Azure Event Hubs namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Event Hubs namespace to require that clients send and receive data with a newer version of TLS. If an Event Hubs namespace requires a minimum version of TLS, then any requests made with an older version will fail. ", "guid": "d2f54b29-769e-43a6-a0e7-828ac936657e", "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend MinimumTlsVersion = tostring(properties.minimumTlsVersion) | extend compliant = iif(MinimumTlsVersion == '1.2' or MinimumTlsVersion == '1.3', true, false) | project name, resourceGroup, location, MinimumTlsVersion, compliant", "service": "Event Hubs", "services": [ "EventHubs" @@ -33402,11 +33632,11 @@ "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-shared-access-signature#shared-access-authorization-policies", "service": "Event Hubs", "services": [ - "EventHubs", - "Entra", - "RBAC", "TrafficManager", - "AzurePolicy" + "RBAC", + "EventHubs", + "AzurePolicy", + "Entra" ], "severity": "Medium", "subcategory": "Identity and Access Management", @@ -33422,11 +33652,11 @@ "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-managed-identity?tabs=latest", "service": "Event Hubs", "services": [ - "AKV", "EventHubs", - "Storage", "VM", - "Entra" + "Storage", + "Entra", + "AKV" ], "severity": "Medium", "subcategory": "Identity and Access Management", @@ -33442,9 +33672,9 @@ "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory#azure-built-in-roles-for-azure-event-hubs", "service": "Event Hubs", "services": [ + "RBAC", "EventHubs", - "Entra", - "RBAC" + "Entra" ], "severity": "High", "subcategory": "Identity and Access Management", @@ -33460,8 +33690,8 @@ "link": "https://learn.microsoft.com/azure/event-hubs/monitor-event-hubs-reference", "service": "Event Hubs", "services": [ - "EventHubs", "Monitor", + "EventHubs", "VNet" ], "severity": "Medium", @@ -33524,10 +33754,11 @@ "description": " This will be turned on automatically for a new EH namespace created from the portal with Premium, Dedicated, or Standard SKUs in a zone-enabled region. Both the EH metadata and the event data itself are replicated across zones", "guid": "f15bce21-9e4a-40eb-9787-9424d226786d", "link": "https://learn.microsoft.com/azure/event-hubs/event-hubs-premium-overview#high-availability-with-availability-zones", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend zoneRedundant = tobool(properties.zoneRedundant) | extend compliant = iff(zoneRedundant == true, true, false) | project name, resourceGroup, zoneRedundant, compliant", "service": "Event Hubs", "services": [ - "ACR", - "EventHubs" + "EventHubs", + "ACR" ], "severity": "High", "subcategory": "Zone Redudancy", @@ -33539,6 +33770,7 @@ "checklist": "Azure Event Hub Review", "guid": "20b56c56-ad58-4519-8f82-735c586bb281", "link": "https://learn.microsoft.com/azure/event-hubs/compare-tiers", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend sku = tostring(sku.name) | extend compliant = iff(sku == 'Premium', true, false) | project name, resourceGroup, location, sku, compliant", "service": "Event Hubs", "services": [ "EventHubs" @@ -33805,9 +34037,9 @@ "service": "Azure Service Fabric", "services": [ "Storage", + "VM", "AKV", - "Entra", - "VM" + "Entra" ], "severity": "Medium", "subcategory": "Cluster architecture", @@ -33912,8 +34144,8 @@ "service": "Spring Apps", "services": [ "ASR", - "FrontDoor", - "TrafficManager" + "TrafficManager", + "FrontDoor" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -34028,9 +34260,9 @@ "guid": "1549ab81-53d8-49f8-ad17-b84b33b5a67f", "link": "https://learn.microsoft.com/azure/well-architected/service-guides/service-bus/reliability#checklist", "services": [ - "ServiceBus", "Storage", - "ASR" + "ASR", + "ServiceBus" ], "severity": "Medium", "subcategory": "Best Practices", @@ -34109,8 +34341,8 @@ "guid": "338ee253-c17d-432e-aaaa-b7571549ab81", "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-outages-disasters#availability-zones", "services": [ - "ACR", - "ServiceBus" + "ServiceBus", + "ACR" ], "severity": "High", "subcategory": "Best Practices", @@ -34124,9 +34356,9 @@ "guid": "53d89f89-d17b-484b-93b5-a67f7b9ed5b3", "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-outages-disasters#geo-disaster-recovery", "services": [ - "ServiceBus", + "Storage", "ASR", - "Storage" + "ServiceBus" ], "severity": "Medium", "subcategory": "Geo-Disaster Recovery", @@ -34140,9 +34372,9 @@ "guid": "1f38c403-a822-4c24-93cf-0f18ac699ef1", "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-federation-overview", "services": [ - "ACR", + "ASR", "ServiceBus", - "ASR" + "ACR" ], "severity": "Medium", "subcategory": "Geo-Disaster Recovery", @@ -34156,8 +34388,8 @@ "guid": "d5a83de4-de32-4c18-a147-0607c5c0e4e6", "link": "https://learn.microsoft.com/azure/architecture/best-practices/data-partitioning-strategies#partitioning-azure-service-bus", "services": [ - "ServiceBus", - "Storage" + "Storage", + "ServiceBus" ], "severity": "Medium", "subcategory": "Best Practices", @@ -34196,9 +34428,9 @@ "guid": "4a69b9d3-39ac-44e7-a68d-1d75657202b4", "link": "https://learn.microsoft.com/azure/well-architected/service-guides/service-bus/reliability#checklist", "services": [ - "PrivateLink", + "Storage", "ServiceBus", - "Storage" + "PrivateLink" ], "severity": "Medium", "subcategory": "Best Practices", @@ -34258,11 +34490,11 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", "service": "Service Bus", "services": [ - "Entra", - "RBAC", "TrafficManager", - "ServiceBus", - "AzurePolicy" + "RBAC", + "AzurePolicy", + "Entra", + "ServiceBus" ], "severity": "Medium", "subcategory": "Identity and Access Management", @@ -34296,11 +34528,11 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", "service": "Service Bus", "services": [ - "Storage", "RBAC", + "Storage", + "Entra", "Subscriptions", - "ServiceBus", - "Entra" + "ServiceBus" ], "severity": "High", "subcategory": "Identity and Access Management", @@ -34316,9 +34548,9 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", "service": "Service Bus", "services": [ - "ServiceBus", "Monitor", - "VNet" + "VNet", + "ServiceBus" ], "severity": "Medium", "subcategory": "Monitoring", @@ -34334,9 +34566,9 @@ "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", "service": "Service Bus", "services": [ - "ServiceBus", "PrivateLink", - "VNet" + "VNet", + "ServiceBus" ], "severity": "Medium", "subcategory": "Networking", @@ -34367,7 +34599,7 @@ "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx", "services": [], "severity": "High", - "subcategory": "High Availablity ", + "subcategory": "High Availablity", "text": "Leverage FTA Resiliency Handbook for Stream Analytics", "waf": "Reliability" }, @@ -34379,7 +34611,7 @@ "link": "https://azure.microsoft.com/en-in/products/stream-analytics", "services": [], "severity": "Medium", - "subcategory": "High Availablity ", + "subcategory": "High Availablity", "text": "Understand High Availability 99% SLA and use it to plan your DR strategy", "waf": "Reliability" }, @@ -34403,7 +34635,7 @@ "services": [], "severity": "Medium", "subcategory": "Geo Redundancy", - "text": "Depending on your availablity requirement, configure Active/Active configuration or Active/Passive configuration ", + "text": "Depending on your availablity requirement, configure Active/Active configuration or Active/Passive configuration", "waf": "Reliability" }, { @@ -34413,14 +34645,27 @@ "guid": "32d41e36-11c8-417b-8afb-c410d4391898", "service": "Azure Synapse Analytics", "services": [ - "Entra", - "SQL" + "SQL", + "Entra" ], "severity": "High", "subcategory": "", "text": "Restrict use of local users on sql workloads on Synapse", "waf": "Security" }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No additional configurations are required as this is enabled on a default deployment.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "Encrypt sensitive data in transit", + "waf": "Security" + }, { "category": "Identity and Access Management", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34436,6 +34681,17 @@ "text": "Use managed identity to authenticate to the services", "waf": "Security" }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "Enable data at rest encryption by default", + "waf": "Security" + }, { "category": "Identity and Access Management", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34451,6 +34707,19 @@ "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Security" }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Keyvaults to store your CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "Use customer-managed key option in data at rest encryption when required", + "waf": "Security" + }, { "category": "Identity and Access Management", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34460,9 +34729,9 @@ "service": "Azure Synapse Analytics", "services": [ "Storage", + "Entra", "RBAC", - "Monitor", - "Entra" + "Monitor" ], "severity": "Medium", "subcategory": "", @@ -34476,8 +34745,8 @@ "link": "https://learn.microsoft.com/sql/relational-databases/security/row-level-security?view=sql-server-ver16&context=%2Fazure%2Fsynapse-analytics%2Fcontext%2Fcontext", "service": "Azure Synapse Analytics", "services": [ - "Entra", - "SQL" + "SQL", + "Entra" ], "severity": "Medium", "subcategory": "", @@ -34499,6 +34768,20 @@ "text": "Use managed vnet workspace to restrict the access over public internet", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Microsoft Entra ID as the default authentication method.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "services": [ + "Entra" + ], + "severity": "High", + "subcategory": "", + "text": "Use Microsoft Entra ID as the default authentication method and disable local access wherever possible", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34514,6 +34797,20 @@ "text": "Configure private endpoints to connect to the external services and disable public access", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Microsoft Entra ID as the default authentication method.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "services": [ + "Entra" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use managed identity to authenticate to the services", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34526,6 +34823,20 @@ "text": "If enabling public access highly recommended to configure IP firewall rules", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "services": [ + "Entra", + "AzurePolicy" + ], + "severity": "Medium", + "subcategory": "", + "text": "Configure conditional access policies to restrict the access on Data plane", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34533,14 +34844,29 @@ "link": "https://learn.microsoft.com/azure/data-factory/create-self-hosted-integration-runtime?tabs=data-factory", "service": "Azure Synapse Analytics", "services": [ - "VM", - "VNet" + "VNet", + "VM" ], "severity": "Medium", "subcategory": "", "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn�t leave your corporate network", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Restrict exposure of keys and secerts", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "services": [ + "AKV", + "Entra" + ], + "severity": "High", + "subcategory": "", + "text": "Use Azure Key Vaults to store secrets and crendentials.", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34554,6 +34880,53 @@ "text": "Enable Data Exfiltration Protection (DEP)", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "services": [ + "Entra" + ], + "severity": "High", + "subcategory": "", + "text": "Separate and limit highly privileged/administrative users", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It�s recommended that you treat this rule like an administrative root account and don�t use it in your application. You can create additional policy rules in the Configure tab for the namespace in the portal, via PowerShell or Azure CLI. Avoid the usage of local authentication methods or accounts, these should be disabled wherever possible. Instead use Azure AD to authenticate where possible.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "services": [ + "EventHubs", + "TrafficManager", + "Entra", + "AzurePolicy" + ], + "severity": "Medium", + "subcategory": "", + "text": "Authenticate access to Event Hubs resources using shared access signatures (SAS) and restrict local users", + "waf": "Security" + }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Azure role-based access control (Azure RBAC) to manage Azure resource access through built-in role assignments. Azure RBAC roles can be assigned to users, groups, service principals, and managed identities.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "services": [ + "RBAC", + "Entra" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use Azure RBACs to fine grain the access ", + "waf": "Security" + }, { "category": "Data Protection", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34569,6 +34942,21 @@ "text": "Data Encryption at rest using Customer managed Keys for workspace", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "services": [ + "VNet", + "Firewall" + ], + "severity": "Medium", + "subcategory": "", + "text": "Disable Public Network Access", + "waf": "Security" + }, { "category": "Data Protection", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34584,6 +34972,19 @@ "text": "Data Encryption in transit ", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "services": [ + "VNet" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use Vnets to isolate traffic over restricted network ", + "waf": "Security" + }, { "category": "Data Protection", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34598,6 +34999,20 @@ "text": "Store passwords, secerts and keys in Azure key vault", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "services": [ + "PrivateLink" + ], + "severity": "Medium", + "subcategory": "", + "text": "Deploy private endpoints for all Azure resources that support the Private Link feature, to establish a private access point for the resources.", + "waf": "Security" + }, { "category": "", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34613,6 +35028,129 @@ "text": "Use Azure Key Vault secrets in pipeline activities", "waf": "Security" }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric controls data access using workspaces. In workspaces, data appears in the form of Fabric items, and users can't view or use items (data) unless you give them access to the workspace. You can find more information about workspace and item permissions, in Permission model.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "services": [ + "RBAC", + "ARS" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use Workspace roles to provide access to the users on the data", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "OneLake RBAC uses role assignments to apply permissions to its members.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "services": [ + "Storage", + "RBAC" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use RBAC on Onelake to provide fine grain access on the data in Tables/Files Onelake ", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Take into account the access of the user at both target and source location of the shortcut", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "services": [ + "Entra" + ], + "severity": "Medium", + "subcategory": "", + "text": "When using shortcuts the user identity of the user should have access on the target location of the shortcut as well", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Not all users need to have access on the entire workspace using roles so instead restrict giving roles on the entire workspace and only share the item to the user using share item feature or managing permission in Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "services": [ + "RBAC" + ], + "severity": "Medium", + "subcategory": "", + "text": "Restrict providing workspace level role to users instead share an item only to the users", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use features like RLS, CLS and Dynamic data masking to enhance your data security requirements on sql workloads.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "services": [ + "EventHubs", + "SQL" + ], + "severity": "Medium", + "subcategory": "", + "text": "Limit access to the data by defining RLS, CLS and dynamic data masking on Warehouse and SQL analytics endpoints", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use features like RLS and OLS on Power BI to have more security features on semantic models", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "Limit access to the data by defining RLS and OLS on semantic models in Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "In Fabric, all data that is stored in OneLake is encrypted at rest", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "Encrypt Data at rest", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Security" + }, + { + "category": "Data Protection", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Data in transit across the public internet between Microsoft services is always encrypted with at least TLS 1.2. Fabric negotiates to TLS 1.3 whenever possible.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "services": [ + "ACR" + ], + "severity": "Medium", + "subcategory": "", + "text": "Encrypt data in transit", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" + }, { "category": "Identity and Access Management", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34627,6 +35165,21 @@ "text": "Restrict use of local users whereever necessary", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No need to do anything. Every request to connect to Fabric is authenticated with Microsoft Entra ID, allowing users to safely connect to Fabric from their corporate office, when working at home, or from a remote location.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "services": [ + "Entra" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use Microsoft Entra ID as default authentication method", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" + }, { "category": "Identity and Access Management", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34642,6 +35195,22 @@ "text": "Use managed identity to authenticate to the services", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "A Fabric workspace identity is an automatically managed service principal that can be associated with a Fabric workspace. Workspace identities can be created in the workspace settings of any workspace except My workspaces. A workspace identity is automatically assigned the workspace contributor role and has access to workspace items. Limitation: Write to shortcut destination fails when using workspace identity as the authentication method. Connections with workspace-identity-authentication can only be used in Onelake shortcuts and data pipelines.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "services": [ + "RBAC", + "Entra" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use workspace identity to authenticate to the services", + "waf": "Security" + }, { "category": "Identity and Access Management", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34657,6 +35226,23 @@ "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Security" }, + { + "category": "Identity and Access Management", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Grant the identity permissions on the storage account", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "services": [ + "Storage", + "Entra", + "RBAC" + ], + "severity": "Medium", + "subcategory": "", + "text": "Provide RBAC roles on storage account to the managed identity to make a successful connection", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34668,20 +35254,53 @@ "text": "Disable access over public internet and configure either firewall rules or trusted services rules", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric workspaces with a workspace identity can securely read or write to firewall-enabled Azure Data Lake Storage Gen2 accounts through�trusted workspace access�for OneLake shortcuts.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "services": [ + "Storage", + "EventHubs", + "Entra" + ], + "severity": "Medium", + "subcategory": "", + "text": "Configure trusted workspace access to access storage account behind firewall ", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "guid": "6898a535-e337-4897-b31b-67d67be5962a", "service": "Azure Data Factory", "services": [ - "VM", - "VNet" + "VNet", + "VM" ], "severity": "Medium", "subcategory": "", "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn�t leave your corporate network", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Managed virtual networks are virtual networks that are created and managed by Microsoft Fabric for each Fabric workspace. Managed virtual networks provide network isolation for Fabric Spark workloads, meaning that the compute clusters are deployed in a dedicated network and are no longer part of the shared virtual network. It is only supported for spark workload in Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "services": [ + "VNet" + ], + "severity": "Medium", + "subcategory": "", + "text": "Use managed vnet option if you have network isolation needs", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34697,6 +35316,22 @@ "text": "Use managed vnet IR to restrict the access over public internet for Azure Integration Runtime", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Managed private endpoints are feature that allows secure and private access to data sources from Fabric Spark workloads. You cannot use starter pool with managed PE", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "services": [ + "PrivateLink" + ], + "severity": "Medium", + "subcategory": "", + "text": "Configure managed private endpoints to access Azure services", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" + }, { "category": "Network Security", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34714,6 +35349,98 @@ "text": "Configure managed private endpoints to connect to resources using managed azure IR", "waf": "Security" }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric uses a private IP address from your virtual network. The endpoint allows users in your network to communicate with Fabric over the private IP address using private links.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "services": [ + "PrivateLink", + "VNet" + ], + "severity": "Medium", + "subcategory": "", + "text": "Configure Private Links to access resources in your own Azure vnet i.e traffic coming in your Fabric environment", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "When a user authenticates access is determined based on a set of policies that might include IP address, location, and managed devices.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "services": [ + "Entra", + "AzurePolicy" + ], + "severity": "Medium", + "subcategory": "", + "text": "Configure Microsoft Entra ID conditional access if a user is trying to access your Fabric environment", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "In Azure, a service tag is a defined group of IP addresses that is automatically managed, as a group, to minimize the complexity of updates or changes to network security rules.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "You can use Azure service tags to enable connections to and from Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "optional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "You can add Fabric URLs to your allowlist", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "optional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "services": [], + "severity": "Medium", + "subcategory": "", + "text": "You can add Power BI URLs to your allowlist", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Security" + }, + { + "category": "Networking", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "The data gateway lets you connect your Azure and other data services to Microsoft Fabric and the Power Platform to securely communicate with the data source, execute queries, and transmit results back to the service.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "services": [ + "EventHubs", + "VNet" + ], + "severity": "Medium", + "subcategory": "", + "text": "Configure and use On-prem data gateway or Vnet data gateway to connect to sources either on prem or behind a virtual network", + "waf": "Security" + }, { "category": "", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -34838,8 +35565,8 @@ "service": "Microsoft Purview", "services": [ "RBAC", - "Entra", - "Subscriptions" + "Subscriptions", + "Entra" ], "severity": "Medium", "subcategory": "", @@ -34963,9 +35690,9 @@ "link": "https://learn.microsoft.com/purview/concept-best-practices-security#use-network-security-groups", "service": "Microsoft Purview", "services": [ - "VM", "PrivateLink", - "VNet" + "VNet", + "VM" ], "severity": "Medium", "subcategory": "", @@ -34979,9 +35706,9 @@ "link": "https://learn.microsoft.com/azure/firewall/overview", "service": "Microsoft Purview", "services": [ - "NVA", "PrivateLink", - "Firewall" + "Firewall", + "NVA" ], "severity": "Medium", "subcategory": "", @@ -35037,8 +35764,8 @@ "guid": "e8cb1231-8ca5-4017-b158-e3fb3aa3c2de", "service": "Microsoft Purview", "services": [ - "VM", - "VNet" + "VNet", + "VM" ], "severity": "High", "subcategory": "", @@ -35117,8 +35844,8 @@ "link": "https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access", "service": "Microsoft Purview", "services": [ - "Entra", - "Subscriptions" + "Subscriptions", + "Entra" ], "severity": "Medium", "subcategory": "", @@ -35160,8 +35887,8 @@ "link": "https://learn.microsoft.com/azure/databricks/security/auth/#single-sign-on", "service": "Azure Databricks", "services": [ - "AzurePolicy", - "Entra" + "Entra", + "AzurePolicy" ], "severity": "High", "subcategory": "", @@ -35221,10 +35948,10 @@ "service": "Azure Databricks", "services": [ "EventHubs", - "Entra", + "AzurePolicy", "Storage", - "SQL", - "AzurePolicy" + "Entra", + "SQL" ], "severity": "Medium", "subcategory": "", @@ -35342,9 +36069,9 @@ "service": "Azure Databricks", "services": [ "Storage", + "SQL", "AKV", - "Backup", - "SQL" + "Backup" ], "severity": "Medium", "subcategory": "", @@ -35488,8 +36215,8 @@ "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", "service": "App Gateway", "services": [ - "AppGW", - "VNet" + "VNet", + "AppGW" ], "severity": "Medium", "subcategory": "App Gateway", @@ -35505,12 +36232,12 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "App Gateway", "services": [ - "VNet", - "NVA", - "Subscriptions", "AppGW", "WAF", - "Entra" + "NVA", + "Entra", + "VNet", + "Subscriptions" ], "severity": "Medium", "subcategory": "App Gateway", @@ -35555,8 +36282,8 @@ "link": "https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2", "service": "App Gateway", "services": [ - "ACR", - "AppGW" + "AppGW", + "ACR" ], "severity": "Medium", "subcategory": "App Gateway", @@ -35571,10 +36298,10 @@ "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "service": "Front Door", "services": [ - "AppGW", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Medium", "subcategory": "App delivery", @@ -35671,8 +36398,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", "service": "App Gateway", "services": [ - "AppGW", "AzurePolicy", + "AppGW", "WAF" ], "severity": "High", @@ -35704,8 +36431,8 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/policy-overview?source=recommendations", "service": "App Gateway", "services": [ - "AppGW", "AzurePolicy", + "AppGW", "WAF" ], "severity": "High", @@ -35853,10 +36580,10 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-secured-hub-app-gateway", "service": "App Gateway", "services": [ - "AppGW", "ExpressRoute", - "VPN", - "VNet" + "VNet", + "AppGW", + "VPN" ], "severity": "Medium", "subcategory": "App Gateway", @@ -36226,8 +36953,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", "service": "Key Vault", "services": [ - "ACR", - "AKV" + "AKV", + "ACR" ], "severity": "Medium", "subcategory": "High Availability", @@ -36271,9 +36998,9 @@ "service": "Key Vault", "services": [ "AKV", - "ASR", "Backup", "Storage", + "ASR", "Subscriptions" ], "severity": "Medium", @@ -36351,8 +37078,8 @@ "service": "Key Vault", "services": [ "ASR", - "AKV", - "EventHubs" + "EventHubs", + "AKV" ], "severity": "Medium", "subcategory": "Business continuity and disaster recovery", @@ -36367,9 +37094,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/rbac-guide?tabs=azure-cli", "service": "Key Vault", "services": [ + "RBAC", "AKV", - "Entra", - "RBAC" + "Entra" ], "severity": "Medium", "subcategory": "Identity and Access Management", @@ -36383,9 +37110,9 @@ "guid": "56c57ba5-9119-4bf8-b8f5-c586c7d9cdc1", "link": "https://azure.microsoft.com/support/legal/sla/virtual-desktop/v1_0/", "services": [ - "VM", "ASR", "AVD", + "VM", "Subscriptions" ], "severity": "High", @@ -36432,9 +37159,9 @@ "guid": "25ab225c-6f4e-4168-9fdd-dea8a4b7cdeb", "link": "https://techcommunity.microsoft.com/t5/azure-virtual-desktop-blog/announcing-general-availability-of-support-for-azure/ba-p/3636262", "services": [ - "ACR", "ASR", - "AVD" + "AVD", + "ACR" ], "severity": "High", "subcategory": "Compute", @@ -36449,8 +37176,8 @@ "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ "ASR", - "VM", "AVD", + "VM", "Backup" ], "severity": "Medium", @@ -36465,11 +37192,11 @@ "guid": "5da58639-ca3a-4961-890b-29663c5e10d", "link": "https://learn.microsoft.com/azure/site-recovery/azure-to-azure-how-to-enable-zone-to-zone-disaster-recovery", "services": [ - "AVD", "Cost", - "ASR", + "VM", "Backup", - "VM" + "ASR", + "AVD" ], "severity": "Medium", "subcategory": "Compute", @@ -36484,10 +37211,10 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/azure-compute-gallery", "services": [ "ACR", - "AVD", - "ASR", + "VM", "Storage", - "VM" + "ASR", + "AVD" ], "severity": "Low", "subcategory": "Dependencies", @@ -36532,11 +37259,11 @@ "guid": "fc4972cc-3cd2-45bf-a707-6e9eab4bed32", "link": "https://docs.microsoft.com/azure/virtual-desktop/disaster-recovery", "services": [ - "AVD", "Backup", - "ASR", + "AzurePolicy", "Storage", - "AzurePolicy" + "ASR", + "AVD" ], "severity": "Medium", "subcategory": "Storage", @@ -36600,10 +37327,10 @@ "link": "https://learn.microsoft.com/azure/azure-netapp-files/cross-region-replication-create-peering", "services": [ "ACR", - "AVD", - "ASR", "Backup", - "Storage" + "Storage", + "ASR", + "AVD" ], "severity": "Medium", "subcategory": "Storage", @@ -36660,8 +37387,8 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/shared-image-galleries", "services": [ "Storage", - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Low", "subcategory": "Golden Images", @@ -36775,9 +37502,9 @@ "guid": "90083845-c587-4cb3-a1ec-16a1d076ef9f", "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ - "Cost", "Storage", - "AVD" + "AVD", + "Cost" ], "severity": "Medium", "subcategory": "MSIX & AppAttach", @@ -36806,8 +37533,8 @@ "link": "https://docs.microsoft.com/azure/virtual-desktop/app-attach-file-share", "services": [ "Storage", - "VM", "AVD", + "VM", "RBAC" ], "severity": "Medium", @@ -36864,8 +37591,8 @@ "guid": "e4633254-3185-40a1-b120-bd563a1c8e9d", "link": "https://docs.microsoft.com/azure/virtual-machines/generation-2", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Medium", "subcategory": "Session Host", @@ -36893,8 +37620,8 @@ "guid": "8468c55a-775c-46ee-a5b8-6ad8844ce3b2", "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology#host-pools", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Capacity Planning", @@ -36908,8 +37635,8 @@ "guid": "4e98495f-d3c0-4af2-aa59-a793395a32a7", "link": "https://learn.microsoft.com/azure/virtual-desktop/terminology?WT.mc_id=Portal-fx#host-pools", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Capacity Planning", @@ -36951,8 +37678,8 @@ "guid": "b3724959-4943-4577-a3a9-e10ff6345f24", "link": "https://learn.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Medium", "subcategory": "Capacity Planning", @@ -36981,9 +37708,9 @@ "guid": "971cc4a4-b1f7-4c12-90e0-1ad96808f00c", "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#azure-virtual-desktop-service-limits", "services": [ - "ACR", "AVD", - "Entra" + "Entra", + "ACR" ], "severity": "Medium", "subcategory": "Capacity Planning", @@ -37012,8 +37739,8 @@ "link": "https://learn.microsoft.com/azure/virtual-desktop/configure-host-pool-personal-desktop-assignment-type?tabs=azure#reassign-a-personal-desktop", "services": [ "Storage", - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Low", "subcategory": "Capacity Planning", @@ -37027,8 +37754,8 @@ "guid": "e1112dbd-7ba0-412e-9b94-ef6e047d2ea2", "link": "https://docs.microsoft.com/windows-server/remote/remote-desktop-services/virtual-machine-recs", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Capacity Planning", @@ -37071,8 +37798,8 @@ "guid": "b47a393a-0803-4272-a479-8b1578b219a4", "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Low", "subcategory": "Capacity Planning", @@ -37101,9 +37828,9 @@ "link": "https://learn.microsoft.com/azure/architecture/example-scenario/wvd/windows-virtual-desktop?toc=%2Fazure%2Fvirtual-desktop%2Ftoc.json&bc=%2Fazure%2Fvirtual-desktop%2Fbreadcrumb%2Ftoc.json", "services": [ "ExpressRoute", - "Storage", "AVD", - "VPN" + "VPN", + "Storage" ], "severity": "Medium", "subcategory": "Clients & Users", @@ -37188,8 +37915,8 @@ "link": "https://docs.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "services": [ "Storage", - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Low", "subcategory": "General", @@ -37265,8 +37992,8 @@ "guid": "347dc560-28a7-41ff-b1cd-15dd2f0d5e77", "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#session-hosts", "services": [ - "VM", "AVD", + "VM", "Entra" ], "severity": "Medium", @@ -37298,8 +38025,8 @@ "services": [ "Storage", "AVD", - "AzurePolicy", - "Entra" + "Entra", + "AzurePolicy" ], "severity": "High", "subcategory": "Active Directory", @@ -37344,10 +38071,10 @@ "guid": "6ceb5443-5125-4922-9442-93bb628537a5", "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#identity", "services": [ - "VNet", "AVD", + "Subscriptions", "Entra", - "Subscriptions" + "VNet" ], "severity": "High", "subcategory": "Requirements", @@ -37406,8 +38133,8 @@ "guid": "ea962a15-9394-46da-a7cc-3923266b2258", "link": "https://learn.microsoft.com/azure/virtual-desktop/prerequisites?tabs=portal#supported-identity-scenarios", "services": [ - "VM", "AVD", + "VM", "Entra" ], "severity": "High", @@ -37437,8 +38164,8 @@ "guid": "5549524b-36c0-4f1a-892b-ab3ca78f5db2", "link": "https://learn.microsoft.com/azure/virtual-desktop/administrative-template", "services": [ - "AVD", "Monitor", + "AVD", "Entra" ], "severity": "Low", @@ -37453,9 +38180,9 @@ "guid": "3334fdf9-1c23-4418-8b65-285269440b4b", "link": "https://learn.microsoft.com/azure/virtual-desktop/management", "services": [ - "VM", + "Monitor", "AVD", - "Monitor" + "VM" ], "severity": "Low", "subcategory": "Management", @@ -37469,8 +38196,8 @@ "guid": "63a08be1-6004-4b4a-a79b-f3239faae113", "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop", "services": [ - "AVD", - "Monitor" + "Monitor", + "AVD" ], "severity": "Medium", "subcategory": "Management", @@ -37484,10 +38211,10 @@ "guid": "7138b820-102c-4e16-be30-1e6e872e52e3", "link": "https://learn.microsoft.com/azure/virtual-desktop/autoscale-scenarios", "services": [ - "Cost", - "VM", + "Monitor", "AVD", - "Monitor" + "VM", + "Cost" ], "severity": "Medium", "subcategory": "Management", @@ -37501,10 +38228,10 @@ "guid": "55f612fe-f215-4f0d-a956-10e7dd96bcbc", "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect", "services": [ - "Cost", - "VM", + "Monitor", "AVD", - "Monitor" + "VM", + "Cost" ], "severity": "Low", "subcategory": "Management", @@ -37518,11 +38245,11 @@ "guid": "79a686ea-d971-4ea0-a9a8-1aea074c94cb", "link": "https://learn.microsoft.com/azure/virtual-desktop/start-virtual-machine-connect-faq#are-vms-automatically-deallocated-when-a-user-stops-using-them", "services": [ - "AVD", - "Monitor", "Cost", "VM", - "AzurePolicy" + "AzurePolicy", + "Monitor", + "AVD" ], "severity": "Low", "subcategory": "Management", @@ -37536,14 +38263,14 @@ "guid": "51bcafca-476a-48fa-9b91-9645a7679f20", "link": "https://learn.microsoft.com/azure/virtual-desktop/tag-virtual-desktop-resources", "services": [ - "ExpressRoute", - "AVD", - "Monitor", + "DNS", "Cost", "VWAN", + "ExpressRoute", "Storage", "VPN", - "DNS" + "Monitor", + "AVD" ], "severity": "Low", "subcategory": "Management", @@ -37557,10 +38284,10 @@ "guid": "611dd68c-5a4b-4252-8e44-a59a9c2399c4", "link": "https://learn.microsoft.com/azure/virtual-desktop/azure-advisor-recommendations", "services": [ - "Cost", "Monitor", "AVD", - "Entra" + "Entra", + "Cost" ], "severity": "Low", "subcategory": "Management", @@ -37574,8 +38301,8 @@ "guid": "04722da2-9c2b-41cd-922f-54b29bade3aa", "link": "https://learn.microsoft.com/mem/intune/fundamentals/azure-virtual-desktop-multi-session", "services": [ - "AVD", - "Monitor" + "Monitor", + "AVD" ], "severity": "Medium", "subcategory": "Management", @@ -37589,8 +38316,8 @@ "guid": "c067939b-e5ca-4698-b9ce-3bd91843e73f", "link": "https://learn.microsoft.com/azure/virtual-desktop/scheduled-agent-updates", "services": [ - "AVD", - "Monitor" + "Monitor", + "AVD" ], "severity": "Low", "subcategory": "Management", @@ -37604,9 +38331,9 @@ "guid": "d1e8c38e-c936-4667-913c-005674b1e944", "link": "https://docs.microsoft.com/azure/virtual-desktop/create-validation-host-pool", "services": [ - "VM", + "Monitor", "AVD", - "Monitor" + "VM" ], "severity": "Medium", "subcategory": "Management", @@ -37620,9 +38347,9 @@ "guid": "a459c373-e7ed-4616-83b3-65a917ecbe48", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-platform-automation-and-devops", "services": [ - "VM", + "Monitor", "AVD", - "Monitor" + "VM" ], "severity": "Medium", "subcategory": "Management", @@ -37636,9 +38363,9 @@ "guid": "ebe54cd7-df2e-48bb-ac35-81559bb9153e", "link": "https://docs.microsoft.com/azure/virtual-desktop/faq", "services": [ - "VM", + "Monitor", "AVD", - "Monitor" + "VM" ], "severity": "Medium", "subcategory": "Management", @@ -37652,8 +38379,8 @@ "guid": "63cfff1c-ac59-49ef-8d5a-83dd4de36c1c", "link": "https://learn.microsoft.com/azure/virtual-desktop/insights", "services": [ - "AVD", - "Monitor" + "Monitor", + "AVD" ], "severity": "High", "subcategory": "Monitoring", @@ -37667,9 +38394,9 @@ "guid": "81770afb-c4c0-4e43-a186-58d2857ed671", "link": "https://docs.microsoft.com/azure/virtual-desktop/diagnostics-log-analytics", "services": [ - "VM", + "Monitor", "AVD", - "Monitor" + "VM" ], "severity": "Medium", "subcategory": "Monitoring", @@ -37699,8 +38426,8 @@ "guid": "18813706-f7c4-4c0d-9e51-4548d2457ed6", "link": "https://docs.microsoft.com/azure/virtual-desktop/set-up-service-alerts", "services": [ - "AVD", - "Monitor" + "Monitor", + "AVD" ], "severity": "Medium", "subcategory": "Monitoring", @@ -37714,10 +38441,10 @@ "guid": "dd399cfd-7b28-4dc8-9555-6202bfe4563b", "link": "https://docs.microsoft.com/azure/architecture/reference-architectures/hybrid-networking/", "services": [ - "NVA", + "ExpressRoute", "AVD", "VPN", - "ExpressRoute" + "NVA" ], "severity": "Medium", "subcategory": "Networking", @@ -37731,8 +38458,8 @@ "guid": "c8639648-a652-4d6c-85e5-02965388e5de", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/wvd/eslz-network-topology-and-connectivity", "services": [ - "VWAN", "AVD", + "VWAN", "VNet" ], "severity": "Medium", @@ -37762,9 +38489,9 @@ "guid": "fc4972cd-3cd2-41bf-9703-6e5e6b4bed3d", "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", "services": [ - "NVA", - "Firewall", "AVD", + "Firewall", + "NVA", "VNet" ], "severity": "Medium", @@ -37793,8 +38520,8 @@ "guid": "73676ae4-6691-4e88-95ad-a42223e13810", "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/onboard-windows-multi-session-device?view=o365-worldwide", "services": [ - "Defender", - "AVD" + "AVD", + "Defender" ], "severity": "Medium", "subcategory": "Networking", @@ -37808,9 +38535,9 @@ "guid": "523181a9-4174-4158-93ff-7ae7c6d37431", "link": "https://docs.microsoft.com/azure/firewall/protect-windows-virtual-desktop", "services": [ - "NVA", - "Firewall", "AVD", + "Firewall", + "NVA", "VNet" ], "severity": "Low", @@ -37825,8 +38552,8 @@ "guid": "cc6edca0-aeca-4566-9e92-cf246f1465af", "link": "https://learn.microsoft.com/azure/virtual-desktop/proxy-server-support", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Networking", @@ -37840,8 +38567,8 @@ "guid": "516785c6-fa96-4c96-ad88-408f372734c8", "link": "https://learn.microsoft.com/azure/virtual-desktop/rdp-bandwidth", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Low", "subcategory": "Networking", @@ -37855,11 +38582,11 @@ "guid": "ec27d589-9178-426d-8df2-ff60020f30a6", "link": "https://learn.microsoft.com/azure/storage/files/storage-files-networking-endpoints", "services": [ - "AVD", + "PrivateLink", "Cost", "Storage", "VNet", - "PrivateLink" + "AVD" ], "severity": "Medium", "subcategory": "Networking", @@ -37902,8 +38629,8 @@ "guid": "b1172576-9ef6-4691-a483-5ac932223ece", "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/deployment-vdi-microsoft-defender-antivirus", "services": [ - "Defender", - "AVD" + "AVD", + "Defender" ], "severity": "High", "subcategory": "Host Configuration", @@ -37918,9 +38645,9 @@ "link": "https://learn.microsoft.com/azure/virtual-machines/disk-encryption-overview", "services": [ "Storage", - "AKV", "AVD", - "VM" + "VM", + "AKV" ], "severity": "Low", "subcategory": "Host Configuration", @@ -37934,9 +38661,9 @@ "guid": "36a5a67f-bb9e-4d5b-9547-8c4479816b28", "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#azure-virtual-desktop-support-for-trusted-launch", "services": [ - "VM", + "Monitor", "AVD", - "Monitor" + "VM" ], "severity": "Medium", "subcategory": "Host Configuration", @@ -37950,8 +38677,8 @@ "guid": "135d3899-4b31-44d3-bc8f-028871a359d8", "link": "https://learn.microsoft.com/windows/whats-new/windows-11-requirements", "services": [ - "VM", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Host Configuration", @@ -38007,8 +38734,8 @@ "guid": "e19dd344-29eb-4722-a237-a151c5bb4e4f", "link": "https://learn.microsoft.com/microsoft-365/security/defender-endpoint/web-protection-overview", "services": [ - "Defender", - "AVD" + "AVD", + "Defender" ], "severity": "Medium", "subcategory": "Management", @@ -38036,12 +38763,12 @@ "guid": "1814387e-5ca9-4c26-a9b3-2ab5bdfc6998", "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#enable-microsoft-defender-for-cloud", "services": [ - "AVD", - "Defender", "AKV", + "VM", "Storage", - "Subscriptions", - "VM" + "Defender", + "AVD", + "Subscriptions" ], "severity": "Medium", "subcategory": "Management", @@ -38055,8 +38782,8 @@ "guid": "a0916a76-4980-4ad0-b278-ee293c1bc352", "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#collect-audit-logs", "services": [ - "AVD", "Monitor", + "AVD", "Entra" ], "severity": "Medium", @@ -38087,8 +38814,8 @@ "guid": "b9ea80c8-0628-49fc-ae63-125aa4c0a284", "link": "https://learn.microsoft.com/azure/virtual-desktop/security-guide#windows-defender-application-control", "services": [ - "Defender", - "AVD" + "AVD", + "Defender" ], "severity": "Medium", "subcategory": "Management", @@ -38146,10 +38873,10 @@ "guid": "5784b6ca-5e9e-4bcf-8b54-c95459ea7369", "link": "https://learn.microsoft.com/azure/storage/files/storage-files-smb-multichannel-performance", "services": [ - "ACR", "Storage", - "Cost", - "AVD" + "ACR", + "AVD", + "Cost" ], "severity": "Low", "subcategory": "Azure Files", @@ -38225,8 +38952,8 @@ "link": "https://docs.microsoft.com/azure/virtual-desktop/store-fslogix-profile", "services": [ "Storage", - "VM", - "AVD" + "AVD", + "VM" ], "severity": "High", "subcategory": "Capacity Planning", @@ -38270,9 +38997,9 @@ "guid": "8aad53cc-79e2-4e86-9673-57c549675c5e", "link": "https://docs.microsoft.com/azure/virtual-desktop/fslogix-containers-azure-files", "services": [ - "Cost", "Storage", - "AVD" + "AVD", + "Cost" ], "severity": "High", "subcategory": "Capacity Planning", @@ -38332,10 +39059,10 @@ "guid": "d34aad5e-8c78-4e1d-9666-7313c405674c", "link": "https://learn.microsoft.com/fslogix/concepts-configuration-examples", "services": [ - "ACR", "Storage", + "AVD", "AKV", - "AVD" + "ACR" ], "severity": "High", "subcategory": "FSLogix", @@ -38365,8 +39092,8 @@ "link": "https://docs.microsoft.com/fslogix/cloud-cache-configuration-reference", "services": [ "Storage", - "VM", - "AVD" + "AVD", + "VM" ], "severity": "Low", "subcategory": "FSLogix", @@ -38482,8 +39209,8 @@ "guid": "32952499-58c8-4e6f-ada5-972e67893d55", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Cost", - "Entra" + "Entra", + "Cost" ], "severity": "Medium", "subcategory": "Cloud Solution Provider", @@ -38526,8 +39253,8 @@ "guid": "ca0fe401-12ad-46fc-8a7e-86293866a9f6", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-recommendations", "services": [ - "Cost", - "Entra" + "Entra", + "Cost" ], "severity": "Medium", "subcategory": "Enterprise Agreement", @@ -38541,9 +39268,9 @@ "guid": "5cf9f485-2784-49b3-9824-75d9b8bdb57b", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-enterprise-agreement#design-considerations", "services": [ - "Cost", + "Subscriptions", "Entra", - "Subscriptions" + "Cost" ], "severity": "Low", "subcategory": "Enterprise Agreement", @@ -38571,9 +39298,9 @@ "guid": "90e87802-602f-4dfb-acea-67c60689f1d7", "link": "https://learn.microsoft.com/azure/cost-management-billing/manage/mca-section-invoice", "services": [ - "Cost", "Storage", - "Entra" + "Entra", + "Cost" ], "severity": "Low", "subcategory": "Microsoft Customer Agreement", @@ -38587,8 +39314,8 @@ "guid": "e81a73f0-84c4-4641-b406-14db3b4d1f50", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", "services": [ - "Cost", - "Entra" + "Entra", + "Cost" ], "severity": "Low", "subcategory": "Microsoft Customer Agreement", @@ -38618,10 +39345,10 @@ "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", "service": "Entra", "services": [ - "ACR", "RBAC", + "Subscriptions", "Entra", - "Subscriptions" + "ACR" ], "severity": "High", "subcategory": "Identity", @@ -38740,9 +39467,9 @@ "guid": "1559ab91-53e8-4908-ae28-c84c33b6b780", "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/identity/adds-extend-domain#vm-recommendations", "services": [ - "ACR", "VM", - "Entra" + "Entra", + "ACR" ], "severity": "High", "subcategory": "Identity", @@ -38770,10 +39497,10 @@ "guid": "f5664b5e-984a-4859-a773-e7d261623a76", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access#prerequisites-for-a-landing-zone---design-recommendations", "services": [ - "ACR", "RBAC", + "Subscriptions", "Entra", - "Subscriptions" + "ACR" ], "severity": "Medium", "subcategory": "Identity", @@ -38896,8 +39623,8 @@ "guid": "9cf5418b-1520-4b7b-add7-88eb28f833e8", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#identity-and-access-management-in-the-azure-landing-zone-accelerator", "services": [ - "Entra", - "VNet" + "VNet", + "Entra" ], "severity": "High", "subcategory": "Landing zones", @@ -38912,10 +39639,10 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-landing-zones#rbac-recommendations", "services": [ "ACR", - "AKV", - "Storage", "RBAC", - "Entra" + "Storage", + "Entra", + "AKV" ], "severity": "Medium", "subcategory": "Landing zones", @@ -38985,8 +39712,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "services": [ "RBAC", - "AzurePolicy", - "Subscriptions" + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -39000,10 +39727,10 @@ "guid": "8bbac757-1559-4ab9-853e-8908ae28c84c", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/resource-org-management-groups#management-group-recommendations", "services": [ - "VWAN", "ExpressRoute", "DNS", - "Subscriptions" + "Subscriptions", + "VWAN" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -39060,10 +39787,10 @@ "guid": "49b82111-2df2-47ee-912e-7f983f630472", "link": "https://learn.microsoft.com/entra/id-governance/access-reviews-overview", "services": [ - "Cost", "RBAC", + "Subscriptions", "AzurePolicy", - "Subscriptions" + "Cost" ], "severity": "High", "subcategory": "Subscriptions", @@ -39091,8 +39818,8 @@ "guid": "c68e1d76-6673-413b-9f56-64b5e984a859", "link": "https://learn.microsoft.com/azure/cost-management-billing/reservations/save-compute-costs-reservations", "services": [ - "Cost", - "Subscriptions" + "Subscriptions", + "Cost" ], "severity": "High", "subcategory": "Subscriptions", @@ -39108,8 +39835,8 @@ "link": "https://learn.microsoft.com/azure/azure-portal/azure-portal-dashboards", "services": [ "Storage", - "Monitor", - "Subscriptions" + "Subscriptions", + "Monitor" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -39123,8 +39850,8 @@ "guid": "ae28c84c-33b6-4b78-88b9-fe5c41049d40", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/get-started/manage-costs", "services": [ - "Cost", - "Subscriptions" + "Subscriptions", + "Cost" ], "severity": "High", "subcategory": "Subscriptions", @@ -39138,8 +39865,8 @@ "guid": "3a923c34-74d0-4001-aac6-a9e01e6a83de", "link": "https://learn.microsoft.com/azure/governance/management-groups/overview", "services": [ - "Entra", - "Subscriptions" + "Subscriptions", + "Entra" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -39154,8 +39881,8 @@ "guid": "5de32c19-9248-4160-9d5d-1e4e614658d3", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/track-costs", "services": [ - "Cost", - "Subscriptions" + "Subscriptions", + "Cost" ], "severity": "Medium", "subcategory": "Subscriptions", @@ -39223,8 +39950,8 @@ "guid": "373f482f-3e39-4d39-8aa4-7e566f6082b6", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-app-delivery", "services": [ - "AppGW", - "FrontDoor" + "FrontDoor", + "AppGW" ], "severity": "Medium", "subcategory": "App delivery", @@ -39253,13 +39980,13 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology", "service": "VNet", "services": [ - "ExpressRoute", + "DNS", "NVA", - "Firewall", + "ExpressRoute", + "Entra", "VPN", "VNet", - "DNS", - "Entra" + "Firewall" ], "severity": "High", "subcategory": "Hub and spoke", @@ -39337,8 +40064,8 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", "service": "VNet", "services": [ - "ACR", - "VNet" + "VNet", + "ACR" ], "severity": "Medium", "subcategory": "Hub and spoke", @@ -39478,8 +40205,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "service": "ExpressRoute", "services": [ - "ACR", - "VNet" + "VNet", + "ACR" ], "severity": "High", "subcategory": "IP plan", @@ -39543,8 +40270,8 @@ "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone", "service": "Public IP Addresses", "services": [ - "ACR", - "VNet" + "VNet", + "ACR" ], "severity": "High", "subcategory": "IP plan", @@ -39559,8 +40286,8 @@ "link": "https://learn.microsoft.com/azure/dns/private-dns-getstarted-portal", "service": "DNS", "services": [ - "DNS", - "VNet" + "VNet", + "DNS" ], "severity": "Medium", "subcategory": "IP plan", @@ -39575,9 +40302,9 @@ "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", "service": "DNS", "services": [ - "ACR", + "VNet", "DNS", - "VNet" + "ACR" ], "severity": "Medium", "subcategory": "IP plan", @@ -39592,8 +40319,8 @@ "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", "service": "DNS", "services": [ - "DNS", - "VNet" + "VNet", + "DNS" ], "severity": "Low", "subcategory": "IP plan", @@ -39608,9 +40335,9 @@ "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", "service": "DNS", "services": [ + "VNet", "VM", - "DNS", - "VNet" + "DNS" ], "severity": "High", "subcategory": "IP plan", @@ -39625,8 +40352,8 @@ "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale#private-link-and-dns-integration-in-hub-and-spoke-network-architectures", "service": "DNS", "services": [ - "DNS", - "VNet" + "VNet", + "DNS" ], "severity": "Medium", "subcategory": "IP plan", @@ -39657,8 +40384,8 @@ "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", "service": "Bastion", "services": [ - "Bastion", - "VNet" + "VNet", + "Bastion" ], "severity": "Medium", "subcategory": "Internet", @@ -39673,10 +40400,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", "service": "WAF", "services": [ - "ACR", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "ACR" ], "severity": "Medium", "subcategory": "Internet", @@ -39691,10 +40418,10 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", "service": "WAF", "services": [ - "AppGW", - "FrontDoor", "AzurePolicy", - "WAF" + "FrontDoor", + "WAF", + "AppGW" ], "severity": "Low", "subcategory": "Internet", @@ -39725,8 +40452,8 @@ "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", "service": "VNet", "services": [ - "DDoS", - "VNet" + "VNet", + "DDoS" ], "severity": "High", "subcategory": "Internet", @@ -39785,8 +40512,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", "service": "ExpressRoute", "services": [ - "Backup", "ExpressRoute", + "Backup", "VPN" ], "severity": "Medium", @@ -39836,8 +40563,8 @@ "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", "service": "ExpressRoute", "services": [ - "Cost", - "ExpressRoute" + "ExpressRoute", + "Cost" ], "severity": "High", "subcategory": "Hybrid", @@ -39853,8 +40580,8 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", "service": "ExpressRoute", "services": [ - "Cost", - "ExpressRoute" + "ExpressRoute", + "Cost" ], "severity": "High", "subcategory": "Hybrid", @@ -39946,8 +40673,8 @@ "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "service": "ExpressRoute", "services": [ - "Cost", - "ExpressRoute" + "ExpressRoute", + "Cost" ], "severity": "High", "subcategory": "Hybrid", @@ -39993,9 +40720,9 @@ "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", "service": "ExpressRoute", "services": [ - "ACR", "Monitor", - "NetworkWatcher" + "NetworkWatcher", + "ACR" ], "severity": "Medium", "subcategory": "Hybrid", @@ -40058,8 +40785,8 @@ "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", "service": "ExpressRoute", "services": [ - "ACR", - "ExpressRoute" + "ExpressRoute", + "ACR" ], "severity": "High", "subcategory": "Hybrid", @@ -40118,8 +40845,8 @@ "service": "ExpressRoute", "services": [ "ExpressRoute", - "Monitor", - "VNet" + "VNet", + "Monitor" ], "severity": "Medium", "subcategory": "Hybrid", @@ -40179,10 +40906,10 @@ "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", "service": "Firewall", "services": [ - "ACR", "RBAC", "Firewall", - "AzurePolicy" + "AzurePolicy", + "ACR" ], "severity": "Medium", "subcategory": "Firewall", @@ -40278,10 +41005,10 @@ "service": "Firewall", "services": [ "NVA", - "Firewall", "VWAN", "Storage", - "VNet" + "VNet", + "Firewall" ], "severity": "High", "subcategory": "Firewall", @@ -40328,8 +41055,8 @@ "link": "https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size", "service": "Firewall", "services": [ - "Firewall", - "VNet" + "VNet", + "Firewall" ], "severity": "High", "subcategory": "Segmentation", @@ -40459,8 +41186,8 @@ "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", "service": "Firewall", "services": [ - "Firewall", - "Monitor" + "Monitor", + "Firewall" ], "severity": "High", "subcategory": "Firewall", @@ -40491,8 +41218,8 @@ "link": "https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell", "service": "Firewall", "services": [ - "ACR", - "Firewall" + "Firewall", + "ACR" ], "severity": "High", "subcategory": "Firewall", @@ -40508,9 +41235,9 @@ "link": "https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview", "service": "Firewall", "services": [ + "VNet", "Firewall", - "DDoS", - "VNet" + "DDoS" ], "severity": "High", "subcategory": "Firewall", @@ -40553,8 +41280,8 @@ "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview", "service": "ExpressRoute", "services": [ - "PrivateLink", - "ExpressRoute" + "ExpressRoute", + "PrivateLink" ], "severity": "Medium", "subcategory": "PaaS", @@ -40585,10 +41312,10 @@ "link": "azure/private-link/inspect-traffic-with-azure-firewall", "service": "Firewall", "services": [ - "NVA", "PrivateLink", "Firewall", - "DNS" + "DNS", + "NVA" ], "severity": "Medium", "subcategory": "PaaS", @@ -40605,8 +41332,8 @@ "service": "ExpressRoute", "services": [ "ExpressRoute", - "VPN", - "VNet" + "VNet", + "VPN" ], "severity": "High", "subcategory": "Segmentation", @@ -40650,8 +41377,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", "service": "NSG", "services": [ - "ACR", - "VNet" + "VNet", + "ACR" ], "severity": "Medium", "subcategory": "Segmentation", @@ -40666,9 +41393,9 @@ "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", "service": "NSG", "services": [ - "NVA", + "VNet", "Entra", - "VNet" + "NVA" ], "severity": "Medium", "subcategory": "Segmentation", @@ -40684,8 +41411,8 @@ "link": "https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview", "service": "NSG", "services": [ - "VNet", - "NetworkWatcher" + "NetworkWatcher", + "VNet" ], "severity": "Medium", "subcategory": "Segmentation", @@ -40731,8 +41458,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/virtual-wan-network-topology#virtual-wan-network-design-recommendationst", "service": "VWAN", "services": [ - "ACR", - "VWAN" + "VWAN", + "ACR" ], "severity": "Medium", "subcategory": "Virtual WAN", @@ -40748,8 +41475,8 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/howto-firewall", "service": "VWAN", "services": [ - "VWAN", - "Firewall" + "Firewall", + "VWAN" ], "severity": "Medium", "subcategory": "Virtual WAN", @@ -40779,8 +41506,8 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", "service": "VWAN", "services": [ - "VWAN", - "Monitor" + "Monitor", + "VWAN" ], "severity": "Medium", "subcategory": "Virtual WAN", @@ -40812,8 +41539,8 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", "service": "VWAN", "services": [ - "VWAN", "ExpressRoute", + "VWAN", "VPN" ], "severity": "Medium", @@ -40891,8 +41618,8 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "service": "Policy", "services": [ - "AzurePolicy", - "Subscriptions" + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", "subcategory": "Governance", @@ -40922,8 +41649,8 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", "service": "Policy", "services": [ - "AzurePolicy", - "Subscriptions" + "Subscriptions", + "AzurePolicy" ], "severity": "Low", "subcategory": "Governance", @@ -40955,9 +41682,9 @@ "service": "Policy", "services": [ "RBAC", + "Subscriptions", "Entra", - "AzurePolicy", - "Subscriptions" + "AzurePolicy" ], "severity": "Medium", "subcategory": "Governance", @@ -40972,8 +41699,8 @@ "link": "https://learn.microsoft.com/azure/governance/policy/overview", "service": "Policy", "services": [ - "AzurePolicy", - "Subscriptions" + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", "subcategory": "Governance", @@ -41003,8 +41730,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/sovereign-landing-zone", "service": "Policy", "services": [ - "AzurePolicy", - "Subscriptions" + "Subscriptions", + "AzurePolicy" ], "severity": "Medium", "subcategory": "Governance", @@ -41045,9 +41772,9 @@ "guid": "29fd366b-a180-452b-9bd7-954b7700c667", "link": "https://learn.microsoft.com/azure/cost-management-billing/costs/tutorial-acm-create-budgets?bc=%2Fazure%2Fcloud-adoption-framework%2F_bread%2Ftoc.json&toc=%2Fazure%2Fcloud-adoption-framework%2Ftoc.json", "services": [ - "Cost", + "Monitor", "TrafficManager", - "Monitor" + "Cost" ], "severity": "Medium", "subcategory": "Optimize your cloud investment", @@ -41062,10 +41789,10 @@ "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/logs/workspace-design#azure-regions", "service": "Monitor", "services": [ - "RBAC", "Monitor", + "Entra", "AzurePolicy", - "Entra" + "RBAC" ], "severity": "Medium", "subcategory": "Monitoring", @@ -41096,8 +41823,8 @@ "service": "Monitor", "services": [ "Storage", - "Monitor", "ARS", + "Monitor", "AzurePolicy" ], "severity": "High", @@ -41113,8 +41840,8 @@ "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", "service": "VM", "services": [ - "VM", "Monitor", + "VM", "AzurePolicy" ], "severity": "Medium", @@ -41351,8 +42078,8 @@ "guid": "0d83fd81-952c-4d47-a6cb-3a930925ef2e", "link": "https://learn.microsoft.com/en-gb/azure/storage/common/redundancy-migration?tabs=portal", "services": [ - "Cost", - "Storage" + "Storage", + "Cost" ], "severity": "High", "subcategory": "Data Protection", @@ -41410,8 +42137,8 @@ "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", "service": "VM", "services": [ - "VM", "Monitor", + "VM", "AzurePolicy" ], "severity": "Medium", @@ -41427,9 +42154,9 @@ "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "service": "VM", "services": [ - "ACR", + "ASR", "VM", - "ASR" + "ACR" ], "severity": "Medium", "subcategory": "Protect and Recover", @@ -41473,9 +42200,9 @@ "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", "service": "WAF", "services": [ - "AppGW", "FrontDoor", - "WAF" + "WAF", + "AppGW" ], "severity": "High", "subcategory": "App delivery", @@ -41491,9 +42218,9 @@ "service": "WAF", "services": [ "Sentinel", - "AppGW", "FrontDoor", - "WAF" + "WAF", + "AppGW" ], "severity": "Medium", "subcategory": "App delivery", @@ -41579,8 +42306,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "AKV", "RBAC", + "AKV", "Entra" ], "severity": "Medium", @@ -41626,9 +42353,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "AKV", "PrivateLink", - "VNet" + "VNet", + "AKV" ], "severity": "Medium", "subcategory": "Encryption and keys", @@ -41643,8 +42370,8 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", "service": "Key Vault", "services": [ - "AKV", "Monitor", + "AKV", "Entra" ], "severity": "Medium", @@ -41705,9 +42432,9 @@ "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", "services": [ - "ACR", "ASR", - "AKV" + "AKV", + "ACR" ], "severity": "Medium", "subcategory": "Encryption and keys", @@ -41768,8 +42495,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", "service": "Defender", "services": [ - "Defender", - "Subscriptions" + "Subscriptions", + "Defender" ], "severity": "High", "subcategory": "Operations", @@ -41784,8 +42511,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", "service": "Defender", "services": [ - "Defender", - "Subscriptions" + "Subscriptions", + "Defender" ], "severity": "High", "subcategory": "Operations", @@ -41800,8 +42527,8 @@ "link": "https://learn.microsoft.com/azure/defender-for-cloud/connect-azure-subscription", "service": "Defender", "services": [ - "Defender", - "Subscriptions" + "Subscriptions", + "Defender" ], "severity": "High", "subcategory": "Operations", @@ -41829,8 +42556,8 @@ "link": "https://learn.microsoft.com/azure/security-center/", "service": "VM", "services": [ - "Defender", - "Monitor" + "Monitor", + "Defender" ], "severity": "Medium", "subcategory": "Operations", @@ -41862,8 +42589,8 @@ "link": "https://learn.microsoft.com/en-us/azure/well-architected/security/monitor-threats#centralized-threat-detection-with-correlated-logs", "service": "Entra", "services": [ - "ACR", - "Entra" + "Entra", + "ACR" ], "severity": "High", "subcategory": "Operations", @@ -42297,10 +43024,10 @@ "guid": "b44fb6ec-bfc1-3a8e-dba2-ca97f0991d2c", "link": "This depends if you have multiple AVS Private Clouds. If so and they are in the same region then use AVS Interconnect. If they are in separate regions then use ExpressRoute Global Reach.", "services": [ - "NVA", - "ASR", "ExpressRoute", - "AVS" + "ASR", + "AVS", + "NVA" ], "severity": "Medium", "subcategory": "Disaster Recovery", @@ -42389,8 +43116,8 @@ "guid": "91f7a87b-21ac-d712-959c-8df2ba034253", "link": "https://learn.microsoft.com/azure/virtual-network/quick-create-portal", "services": [ - "AVS", - "VNet" + "VNet", + "AVS" ], "severity": "Medium", "subcategory": "Hub & Spoke", @@ -42404,10 +43131,10 @@ "guid": "58a027e2-f37f-b540-45d5-e44843aba26b", "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", "services": [ - "VPN", "ExpressRoute", + "VNet", "AVS", - "VNet" + "VPN" ], "severity": "Medium", "subcategory": "Hub & Spoke", @@ -42421,10 +43148,10 @@ "guid": "d4806549-0913-3e79-b580-ac2d3706e65a", "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", "services": [ - "VPN", "ExpressRoute", + "VNet", "AVS", - "VNet" + "VPN" ], "severity": "Medium", "subcategory": "Hub & Spoke", @@ -42438,10 +43165,10 @@ "guid": "864d7a8b-7016-c769-a717-61af6bfb73d2", "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings", "services": [ - "VPN", "ExpressRoute", + "VNet", "AVS", - "VNet" + "VPN" ], "severity": "Medium", "subcategory": "Hub & Spoke", @@ -42455,8 +43182,8 @@ "guid": "cc2e11b9-7911-7da1-458c-d7fcef794aad", "link": "https://learn.microsoft.com/azure/azure-vmware/enable-public-internet-access", "services": [ - "NVA", - "AVS" + "AVS", + "NVA" ], "severity": "Medium", "subcategory": "Internet", @@ -42485,9 +43212,9 @@ "guid": "6f8e93a2-44b1-bb1d-28a1-4d5b3c2ea857", "link": "https://learn.microsoft.com/azure/bastion/tutorial-create-host-portal", "services": [ + "VNet", "AVS", - "Bastion", - "VNet" + "Bastion" ], "severity": "Medium", "subcategory": "Jumpbox & Bastion", @@ -42517,8 +43244,8 @@ "guid": "9988598f-2a9f-6b12-9b46-488415ceb325", "link": "https://learn.microsoft.com/azure/azure-vmware/configure-site-to-site-vpn-gateway", "services": [ - "VPN", - "AVS" + "AVS", + "VPN" ], "severity": "Medium", "subcategory": "VPN", @@ -42532,8 +43259,8 @@ "guid": "956ce5e9-a862-fe2b-a50d-a22923569357", "link": "https://www.omnicalculator.com/other/data-transfer#:~:text=To%20calculate%20the%20data%20transfer%20speed%3A%201%20Download,measured%20time%20to%20find%20the%20data%20transfer%20speed.", "services": [ - "VPN", - "AVS" + "AVS", + "VPN" ], "severity": "Medium", "subcategory": "VPN", @@ -42547,8 +43274,8 @@ "guid": "e095116f-0bdc-4b51-4d71-b9e469d56f59", "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/azure-vmware-solution-foundation-networking", "services": [ - "VPN", - "AVS" + "AVS", + "VPN" ], "severity": "Medium", "subcategory": "VPN", @@ -42578,8 +43305,8 @@ "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-point-to-site-portal", "services": [ "VWAN", - "VPN", - "AVS" + "AVS", + "VPN" ], "severity": "Medium", "subcategory": "vWAN hub", @@ -42609,8 +43336,8 @@ "guid": "fbc47fbf-bc96-fa93-ed5d-8c9be63cd5c3", "link": "https://learn.microsoft.com/azure/azure-vmware/configure-identity-source-vcenter", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Access", @@ -42624,8 +43351,8 @@ "guid": "b5db7975-f6bb-8ba3-ee5f-e3e805887997", "link": "https://learn.microsoft.com/windows-server/identity/ad-ds/plan/understanding-active-directory-site-topology", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Access", @@ -42639,8 +43366,8 @@ "guid": "c30749c4-e2af-558c-2eb9-0b6ae84881d1", "link": "https://learn.microsoft.com/azure/azure-vmware/configure-identity-source-vcenter", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Access", @@ -42654,8 +43381,8 @@ "guid": "64cb9b5c-9edd-787e-1dd8-2b2338e51635", "link": "https://learn.microsoft.com/azure/azure-vmware/configure-external-identity-source-nsx-t", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Access", @@ -42669,8 +43396,8 @@ "guid": "bec285ab-037e-d629-81d1-f61dac23cd4c", "link": "https://youtu.be/4jvfbsrhnEs", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security", @@ -42685,8 +43412,8 @@ "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-identity", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security", @@ -42701,8 +43428,8 @@ "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-identity#view-the-vcenter-server-privileges", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security", @@ -42717,8 +43444,8 @@ "link": "Best practice", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security", @@ -42733,8 +43460,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security ", @@ -42749,8 +43476,8 @@ "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", "services": [ "RBAC", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security ", @@ -42765,8 +43492,8 @@ "link": "Best practice", "services": [ "Monitor", - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security ", @@ -42780,8 +43507,8 @@ "guid": "7effa0c0-9172-e8e4-726a-67dbea8be40a", "link": "https://learn.microsoft.com/azure/azure-vmware/rotate-cloudadmin-credentials?tabs=azure-portal", "services": [ - "AVS", - "Entra" + "Entra", + "AVS" ], "severity": "Medium", "subcategory": "Security ", @@ -42795,8 +43522,8 @@ "guid": "8f426fd0-d73b-d398-1f6f-df0cbe262a82", "link": "https://learn.microsoft.com/azure/azure-arc/vmware-vsphere/overview", "services": [ - "Arc", "VM", + "Arc", "AVS" ], "severity": "Medium", @@ -42812,8 +43539,8 @@ "link": "https://docs.microsoft.com/azure/governance/policy/overview", "services": [ "Monitor", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Operations", @@ -42915,11 +43642,11 @@ "guid": "0962606c-e3b4-62a9-5661-e4ffd62a4509", "link": "https://docs.microsoft.com/azure/azure-vmware/set-up-backup-server-for-azure-vmware-solution", "services": [ - "Monitor", "AVS", - "Backup", "VM", - "AzurePolicy" + "Backup", + "AzurePolicy", + "Monitor" ], "severity": "Medium", "subcategory": "Backup", @@ -42934,8 +43661,8 @@ "link": "https://docs.microsoft.com/azure/azure-vmware/configure-alerts-for-azure-vmware-solution", "services": [ "Monitor", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Capacity", @@ -42949,10 +43676,10 @@ "guid": "7f8f175d-13f4-5298-9e61-0bc7e9fcc279", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/govern", "services": [ - "Cost", "Monitor", + "Subscriptions", "AVS", - "Subscriptions" + "Cost" ], "severity": "Medium", "subcategory": "Costs", @@ -42967,8 +43694,8 @@ "link": "https://docs.microsoft.com/azure/azure-portal/azure-portal-dashboards", "services": [ "Monitor", - "AVS", - "NetworkWatcher" + "NetworkWatcher", + "AVS" ], "severity": "Medium", "subcategory": "Dashboard", @@ -42982,9 +43709,9 @@ "guid": "f9afdcc9-649d-d840-9fb5-a3c0edcc697d", "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", "services": [ - "Storage", "Monitor", - "AVS" + "AVS", + "Storage" ], "severity": "Medium", "subcategory": "Logs & Metrics", @@ -43013,8 +43740,8 @@ "guid": "b243521a-644d-f865-7fb6-21f9019c0dd2", "link": "https://docs.microsoft.com/azure/azure-vmware/configure-vmware-syslogs", "services": [ - "VM", "Monitor", + "VM", "AVS" ], "severity": "Medium", @@ -43029,11 +43756,11 @@ "guid": "2ca97d91-dd36-7229-b668-01036ccc3cd3", "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", "services": [ - "ExpressRoute", "AVS", - "Monitor", + "NetworkWatcher", + "ExpressRoute", "VPN", - "NetworkWatcher" + "Monitor" ], "severity": "Medium", "subcategory": "Network", @@ -43047,9 +43774,9 @@ "guid": "99209143-60fe-19f0-5633-8b5671277ba5", "link": "https://learn.microsoft.com/azure/network-watcher/connection-monitor-create-using-portal", "services": [ - "ExpressRoute", "Monitor", - "AVS" + "AVS", + "ExpressRoute" ], "severity": "Medium", "subcategory": "Network", @@ -43123,8 +43850,8 @@ "guid": "fb00b69a-83ec-ce72-446e-6c23a0cab09a", "link": "https://docs.microsoft.com/azure/azure-monitor/agents/agent-windows?tabs=setup-wizard", "services": [ - "VM", "Monitor", + "VM", "AVS" ], "severity": "Medium", @@ -43167,9 +43894,9 @@ "guid": "ebd3cc3c-ac3d-4293-950d-cecd8445a523", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-network-topology-connectivity", "services": [ - "NVA", "ARS", - "AVS" + "AVS", + "NVA" ], "severity": "Medium", "subcategory": "Hub & Spoke", @@ -43212,10 +43939,10 @@ "guid": "e942c03d-beaa-3d9f-0526-9b26cd5e9937", "link": "Research and choose optimal solution for each application", "services": [ - "NVA", "AppGW", "FrontDoor", - "AVS" + "AVS", + "NVA" ], "severity": "Medium", "subcategory": "Internet", @@ -43244,15 +43971,15 @@ "guid": "66c97b30-81b9-139a-cc76-dd1d94aef42a", "link": "https://docs.microsoft.com/azure/ddos-protection/manage-ddos-protection", "services": [ - "ExpressRoute", - "AVS", "LoadBalancer", - "FrontDoor", "AppGW", - "VPN", - "VNet", + "DDoS", + "AVS", "VM", - "DDoS" + "FrontDoor", + "ExpressRoute", + "VPN", + "VNet" ], "severity": "Medium", "subcategory": "Security", @@ -43325,8 +44052,8 @@ "guid": "7d049005-eb35-4a93-50a5-3b31a9f61161", "link": "https://docs.microsoft.com/azure/azure-vmware/configure-nsx-network-components-azure-portal", "services": [ - "AVS", - "Subscriptions" + "Subscriptions", + "AVS" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -43341,8 +44068,8 @@ "link": "https://docs.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/eslz-platform-automation-and-devops#automated-scale", "services": [ "Storage", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Automated Scale", @@ -43456,8 +44183,8 @@ "guid": "e52d1615-9cc6-565c-deb6-743ed7e90f4b", "link": "Internal policy or regulatory compliance", "services": [ - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Pre-deployment", @@ -43499,8 +44226,8 @@ "guid": "96c76997-30a6-bb92-024d-f4f93f5f57fa", "link": "Done through the subscription/resource providers/ AVS register in the portal", "services": [ - "AVS", - "Subscriptions" + "Subscriptions", + "AVS" ], "severity": "Medium", "subcategory": "Pre-deployment", @@ -43514,8 +44241,8 @@ "guid": "5898e3ff-5e6b-bee1-6f85-22fee261ce63", "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/azure-vmware/enterprise-scale-landing-zone", "services": [ - "AVS", - "Subscriptions" + "Subscriptions", + "AVS" ], "severity": "Medium", "subcategory": "Pre-deployment", @@ -43571,8 +44298,8 @@ "guid": "0c87f999-e517-21ef-f355-f210ad4134d2", "link": "https://docs.vmware.com/en/VMware-NSX-T-Data-Center/3.2/installation/GUID-4B3860B8-1883-48CA-B2F3-7C2205D91D6D.html", "services": [ - "AVS", - "VNet" + "VNet", + "AVS" ], "severity": "Medium", "subcategory": "Pre-deployment", @@ -43614,8 +44341,8 @@ "guid": "f2b73c4f-3d46-32c9-5df1-5b8dfcd3947f", "link": "https://azure.microsoft.com/en-ca/pricing/details/azure-vmware/#:~:text=Azure%20VMware%20Solution%20%20%20%20Instance%20size,TB%20%28all%20NVMe%29%20%20%20N%2FA%20%2Fhour%20", "services": [ - "Cost", - "AVS" + "AVS", + "Cost" ], "severity": "Medium", "subcategory": "Pre-deployment", @@ -43687,8 +44414,8 @@ "guid": "c1a81638-18df-0ce9-a73a-4b9a8a8dd392", "link": "https://docs.microsoft.com/azure/azure-vmware/concepts-storage#data-at-rest-encryption", "services": [ - "AVS", - "SQL" + "SQL", + "AVS" ], "severity": "Medium", "subcategory": "Encryption", @@ -43702,8 +44429,8 @@ "guid": "8d0a8f51-8d35-19cd-c2fe-4e3512fb467e", "link": "https://docs.microsoft.com/azure/key-vault/general/authentication", "services": [ - "AKV", "ExpressRoute", + "AKV", "AVS" ], "severity": "Medium", @@ -43762,8 +44489,8 @@ "guid": "bcdd2348-3d0e-c6bb-1092-aa4cd1a66d6b", "link": "https://docs.microsoft.com/azure/azure-vmware/azure-security-integration", "services": [ - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Security", @@ -43995,9 +44722,9 @@ "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", "services": [ "Storage", + "AzurePolicy", "VM", - "AVS", - "AzurePolicy" + "AVS" ], "severity": "Medium", "subcategory": "Storage", @@ -44012,9 +44739,9 @@ "link": "https://learn.microsoft.com/azure/azure-vmware/configure-storage-policy", "services": [ "Storage", + "AzurePolicy", "VM", - "AVS", - "AzurePolicy" + "AVS" ], "severity": "Medium", "subcategory": "Storage", @@ -44029,8 +44756,8 @@ "link": "https://learn.microsoft.com/azure/azure-vmware/concepts-storage#storage-policies-and-fault-tolerance", "services": [ "Storage", - "AVS", - "AzurePolicy" + "AzurePolicy", + "AVS" ], "severity": "Medium", "subcategory": "Storage", @@ -44181,9 +44908,9 @@ "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", "service": "APIM", "services": [ - "ACR", "AzurePolicy", - "APIM" + "APIM", + "ACR" ], "severity": "Medium", "subcategory": "Development best practices", @@ -44346,9 +45073,9 @@ "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", "service": "APIM", "services": [ - "ACR", "ASR", - "APIM" + "APIM", + "ACR" ], "severity": "Medium", "subcategory": "Business continuity and disaster recovery", @@ -44556,8 +45283,8 @@ "service": "APIM", "services": [ "FrontDoor", - "Entra", - "APIM" + "APIM", + "Entra" ], "severity": "Medium", "subcategory": "Connectivity", @@ -44586,8 +45313,8 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", "service": "APIM", "services": [ - "VNet", "Monitor", + "VNet", "Entra", "APIM" ], @@ -44603,8 +45330,8 @@ "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", "service": "APIM", "services": [ - "VNet", "PrivateLink", + "VNet", "Entra", "APIM" ], @@ -44794,8 +45521,8 @@ "services": [ "WAF", "AppGW", - "Entra", - "APIM" + "APIM", + "Entra" ], "severity": "High", "subcategory": "Network", @@ -44852,8 +45579,8 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/high-availability#multiple-write-regions", "service": "CosmosDB", "services": [ - "ACR", - "CosmosDB" + "CosmosDB", + "ACR" ], "severity": "Medium", "subcategory": "High Availability", @@ -44868,8 +45595,8 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/high-availability#slas", "service": "CosmosDB", "services": [ - "ACR", - "CosmosDB" + "CosmosDB", + "ACR" ], "severity": "Medium", "subcategory": "High Availability", @@ -44915,8 +45642,8 @@ "service": "CosmosDB", "services": [ "Storage", - "Backup", - "CosmosDB" + "CosmosDB", + "Backup" ], "severity": "Medium", "subcategory": "Backup Strategy", @@ -44932,8 +45659,8 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/periodic-backup-restore-introduction", "service": "CosmosDB", "services": [ - "Backup", - "CosmosDB" + "CosmosDB", + "Backup" ], "severity": "Medium", "subcategory": "Backup Strategy", @@ -44949,8 +45676,8 @@ "link": "https://learn.microsoft.com/azure/cosmos-db/continuous-backup-restore-introduction", "service": "CosmosDB", "services": [ - "Backup", - "CosmosDB" + "CosmosDB", + "Backup" ], "severity": "Medium", "subcategory": "Backup Strategy", @@ -45095,8 +45822,8 @@ "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/sharing-metadata-across-different-databricks-workspaces-using/ba-p/3679757", "service": "Azure Data Factory", "services": [ - "ACR", - "Backup" + "Backup", + "ACR" ], "severity": "Medium", "subcategory": "Backup", @@ -45208,8 +45935,8 @@ "guid": "67b23587-05a1-4652-aded-fa8a488cdec4", "link": "https://learn.microsoft.com/azure/site-recovery/azure-to-azure-how-to-enable-policy", "services": [ - "VM", "ASR", + "VM", "AzurePolicy" ], "severity": "High", @@ -45395,7 +46122,7 @@ ], "metadata": { "name": "Master checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/datasecurity_checklist.en.json b/checklists/datasecurity_checklist.en.json index 9475f584..5bbb6f5f 100644 --- a/checklists/datasecurity_checklist.en.json +++ b/checklists/datasecurity_checklist.en.json @@ -11,6 +11,18 @@ "id": "A01.01", "severity": "High" }, + { + "category": "Data Protection", + "subcategory": "", + "text": "Encrypt sensitive data in transit", + "description": "No additional configurations are required as this is enabled on a default deployment.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "id": "A01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version" + }, { "category": "Identity and Access Management", "subcategory": "", @@ -23,6 +35,16 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/synapse-analytics/synapse-service-identity?context=%2Fazure%2Fsynapse-analytics%2Fcontext%2Fcontext" }, + { + "category": "Data Protection", + "subcategory": "", + "text": "Enable data at rest encryption by default", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "id": "A01.02", + "severity": "Medium" + }, { "category": "Identity and Access Management", "subcategory": "", @@ -34,6 +56,18 @@ "id": "A01.03", "severity": "High" }, + { + "category": "Data Protection", + "subcategory": "", + "text": "Use customer-managed key option in data at rest encryption when required", + "description": "Use Keyvaults to store your CMK", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "id": "A01.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault" + }, { "category": "Identity and Access Management", "subcategory": "", @@ -69,6 +103,17 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/synapse-analytics/security/synapse-workspace-managed-vnet?view=sql-server-ver16" }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use Microsoft Entra ID as the default authentication method and disable local access wherever possible", + "description": "Use Microsoft Entra ID as the default authentication method.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "id": "B01.01", + "severity": "High" + }, { "category": "Network Security", "subcategory": "", @@ -81,6 +126,17 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/synapse-analytics/security/synapse-workspace-managed-private-endpoints?view=sql-server-ver16" }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use managed identity to authenticate to the services", + "description": "Use Microsoft Entra ID as the default authentication method.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "id": "B01.02", + "severity": "Medium" + }, { "category": "Network Security", "subcategory": "", @@ -92,6 +148,16 @@ "id": "B01.03", "link": "https://learn.microsoft.com/azure/synapse-analytics/security/synapse-workspace-ip-firewall" }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Configure conditional access policies to restrict the access on Data plane", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "id": "B01.03", + "severity": "Medium" + }, { "category": "Network Security", "subcategory": "", @@ -103,6 +169,17 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/data-factory/create-self-hosted-integration-runtime?tabs=data-factory" }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use Azure Key Vaults to store secrets and crendentials.", + "description": "Restrict exposure of keys and secerts", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "B01.04", + "severity": "High" + }, { "category": "Network Security", "subcategory": "", @@ -115,6 +192,40 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/synapse-analytics/security/how-to-create-a-workspace-with-data-exfiltration-protection" }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Separate and limit highly privileged/administrative users", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "id": "B01.05", + "severity": "High" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Authenticate access to Event Hubs resources using shared access signatures (SAS) and restrict local users", + "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It\ufffds recommended that you treat this rule like an administrative root account and don\ufffdt use it in your application. You can create additional policy rules in the Configure tab for the namespace in the portal, via PowerShell or Azure CLI. Avoid the usage of local authentication methods or accounts, these should be disabled wherever possible. Instead use Azure AD to authenticate where possible.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "id": "B01.06", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use Azure RBACs to fine grain the access ", + "description": "Use Azure role-based access control (Azure RBAC) to manage Azure resource access through built-in role assignments. Azure RBAC roles can be assigned to users, groups, service principals, and managed identities.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "id": "B01.07", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory" + }, { "category": "Data Protection", "subcategory": "", @@ -127,6 +238,17 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/synapse-analytics/security/workspaces-encryption" }, + { + "category": "Networking", + "subcategory": "", + "text": "Disable Public Network Access", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "id": "C01.01", + "severity": "Medium" + }, { "category": "Data Protection", "subcategory": "", @@ -139,6 +261,16 @@ "severity": "Medium", "link": "https://learn.microsoft.com/azure/synapse-analytics/guidance/security-white-paper-data-protection#data-in-transit" }, + { + "category": "Networking", + "subcategory": "", + "text": "Use Vnets to isolate traffic over restricted network ", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "id": "C01.02", + "severity": "Medium" + }, { "category": "Data Protection", "subcategory": "", @@ -150,6 +282,17 @@ "id": "C01.03", "severity": "High" }, + { + "category": "Networking", + "subcategory": "", + "text": "Deploy private endpoints for all Azure resources that support the Private Link feature, to establish a private access point for the resources.", + "waf": "Security", + "service": "Azure Event Hubs", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "id": "C01.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service" + }, { "category": "", "subcategory": "", @@ -163,91 +306,342 @@ "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities" }, { - "category": "Identity and Access Management", + "category": "Data Protection", "subcategory": "", - "text": "Restrict use of local users whereever necessary", - "description": "Restrict the use of local authentication methods for data plane access. Instead, use Microsoft Entra ID as the default authentication method to control your data plane access.", + "text": "Use Workspace roles to provide access to the users on the data", + "description": "Fabric controls data access using workspaces. In workspaces, data appears in the form of Fabric items, and users can't view or use items (data) unless you give them access to the workspace. You can find more information about workspace and item permissions, in Permission model.", "waf": "Security", - "service": "Azure Data Factory", - "guid": "0bdf4cc2-efc4-4d76-8c31-d25ffbb47a39", - "id": "E01.01", - "severity": "High" + "service": "Microsoft Fabric", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "id": "D01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/fabric/security/permission-model" }, { - "category": "Identity and Access Management", + "category": "Data Protection", "subcategory": "", - "text": "Use managed identity to authenticate to the services", - "description": "Managed identities eliminate the need to manage credentials. Managed identities provide an identity for the service instance when connecting to resources that support Microsoft Entra authentication.", + "text": "Use RBAC on Onelake to provide fine grain access on the data in Tables/Files Onelake ", + "description": "OneLake RBAC uses role assignments to apply permissions to its members.", "waf": "Security", - "service": "Azure Data Factory", - "guid": "3a040ed3-2947-498b-8178-a2c5a46ceb54", - "id": "E01.02", + "service": "Microsoft Fabric", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "id": "D01.02", "severity": "Medium", - "link": "https://learn.microsoft.com/azure/data-factory/data-factory-service-identity" + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model" }, { - "category": "Identity and Access Management", + "category": "Data Protection", "subcategory": "", - "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", - "description": "If not required for routine administrative operations, disable or restrict any local admin accounts for only emergency use.", + "text": "When using shortcuts the user identity of the user should have access on the target location of the shortcut as well", + "description": "Take into account the access of the user at both target and source location of the shortcut", "waf": "Security", - "service": "Azure Data Factory", - "guid": "4350d092-d234-4292-a752-8537a551c5bf", - "id": "E01.03", - "severity": "High" + "service": "Microsoft Fabric", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "id": "D01.03", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts" }, { - "category": "Network Security", + "category": "Data Protection", "subcategory": "", - "text": "Disable access over public internet and configure either firewall rules or trusted services rules", - "service": "Azure Data Factory", + "text": "Restrict providing workspace level role to users instead share an item only to the users", + "description": "Not all users need to have access on the entire workspace using roles so instead restrict giving roles on the entire workspace and only share the item to the user using share item feature or managing permission in Fabric", "waf": "Security", - "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", - "id": "F01.01", - "severity": "Medium" + "service": "Microsoft Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "id": "D01.04", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "link": "https://learn.microsoft.com/fabric/get-started/share-items" }, { - "category": "Network Security", + "category": "Data Protection", "subcategory": "", - "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn\ufffdt leave your corporate network", + "text": "Limit access to the data by defining RLS, CLS and dynamic data masking on Warehouse and SQL analytics endpoints", + "description": "Use features like RLS, CLS and Dynamic data masking to enhance your data security requirements on sql workloads.", "waf": "Security", - "service": "Azure Data Factory", - "guid": "6898a535-e337-4897-b31b-67d67be5962a", - "id": "F01.02", - "severity": "Medium" + "service": "Microsoft Fabric", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "id": "D01.05", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security" }, { - "category": "Network Security", + "category": "Data Protection", "subcategory": "", - "text": "Use managed vnet IR to restrict the access over public internet for Azure Integration Runtime", - "description": "When you create an Azure integration runtime within a Data Factory managed virtual network, the integration runtime is provisioned with the managed virtual network. It uses private endpoints to securely connect to supported data stores.", + "text": "Limit access to the data by defining RLS and OLS on semantic models in Power BI", + "description": "Use features like RLS and OLS on Power BI to have more security features on semantic models", "waf": "Security", - "service": "Azure Data Factory", - "guid": "1193846d-697c-4c39-8ed1-6b2d186f0a12", - "id": "F01.03", - "severity": "Medium" + "service": "Microsoft Fabric", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "id": "D01.06", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security" }, { - "category": "Network Security", + "category": "Data Protection", "subcategory": "", - "text": "Configure managed private endpoints to connect to resources using managed azure IR", - "description": "Managed private endpoints are private endpoints created in the Data Factory managed virtual network that establishes a private link to Azure resources. Data Factory manages these private endpoints on your behalf.", + "text": "Encrypt Data at rest", + "description": "In Fabric, all data that is stored in OneLake is encrypted at rest", "waf": "Security", - "service": "Azure Data Factory", - "guid": "41bddde6-8a47-47cd-bb48-61bc3bc10ae6", - "id": "F01.04", + "service": "Microsoft Fabric", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "id": "D01.07", "severity": "Medium", - "link": "https://learn.microsoft.com/azure/data-factory/managed-virtual-network-private-endpoint#managed-private-endpoints" + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/" }, { - "category": "", + "category": "Data Protection", "subcategory": "", - "text": "Configure Private Links to connect to sources in customer Vnet and data factory", - "description": "By using Azure Private Link, you can connect to various platform as a service (PaaS) deployments in Azure via a private endpoint. A private endpoint is a private IP address within a specific virtual network and subnet", - "guid": "b47a393a-0804-4272-a479-8b1578b219a4", - "service": "Azure Data Factory", + "text": "Encrypt data in transit", + "description": "Data in transit across the public internet between Microsoft services is always encrypted with at least TLS 1.2. Fabric negotiates to TLS 1.3 whenever possible.", "waf": "Security", - "id": "G01.01", + "service": "Microsoft Fabric", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "id": "D01.08", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Restrict use of local users whereever necessary", + "description": "Restrict the use of local authentication methods for data plane access. Instead, use Microsoft Entra ID as the default authentication method to control your data plane access.", + "waf": "Security", + "service": "Azure Data Factory", + "guid": "0bdf4cc2-efc4-4d76-8c31-d25ffbb47a39", + "id": "E01.01", + "severity": "High" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use Microsoft Entra ID as default authentication method", + "description": "No need to do anything. Every request to connect to Fabric is authenticated with Microsoft Entra ID, allowing users to safely connect to Fabric from their corporate office, when working at home, or from a remote location.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "id": "E01.01", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use managed identity to authenticate to the services", + "description": "Managed identities eliminate the need to manage credentials. Managed identities provide an identity for the service instance when connecting to resources that support Microsoft Entra authentication.", + "waf": "Security", + "service": "Azure Data Factory", + "guid": "3a040ed3-2947-498b-8178-a2c5a46ceb54", + "id": "E01.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-service-identity" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Use workspace identity to authenticate to the services", + "description": "A Fabric workspace identity is an automatically managed service principal that can be associated with a Fabric workspace. Workspace identities can be created in the workspace settings of any workspace except My workspaces. A workspace identity is automatically assigned the workspace contributor role and has access to workspace items. Limitation: Write to shortcut destination fails when using workspace identity as the authentication method. Connections with workspace-identity-authentication can only be used in Onelake shortcuts and data pipelines.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "id": "E01.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", + "description": "If not required for routine administrative operations, disable or restrict any local admin accounts for only emergency use.", + "waf": "Security", + "service": "Azure Data Factory", + "guid": "4350d092-d234-4292-a752-8537a551c5bf", + "id": "E01.03", + "severity": "High" + }, + { + "category": "Identity and Access Management", + "subcategory": "", + "text": "Provide RBAC roles on storage account to the managed identity to make a successful connection", + "description": "Grant the identity permissions on the storage account", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "id": "E01.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account" + }, + { + "category": "Network Security", + "subcategory": "", + "text": "Disable access over public internet and configure either firewall rules or trusted services rules", + "service": "Azure Data Factory", + "waf": "Security", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "id": "F01.01", + "severity": "Medium" + }, + { + "category": "Networking", + "subcategory": "", + "text": "Configure trusted workspace access to access storage account behind firewall ", + "description": "Fabric workspaces with a workspace identity can securely read or write to firewall-enabled Azure Data Lake Storage Gen2 accounts through\ufffdtrusted workspace access\ufffdfor OneLake shortcuts.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "id": "F01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access" + }, + { + "category": "Network Security", + "subcategory": "", + "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn\ufffdt leave your corporate network", + "waf": "Security", + "service": "Azure Data Factory", + "guid": "6898a535-e337-4897-b31b-67d67be5962a", + "id": "F01.02", + "severity": "Medium" + }, + { + "category": "Networking", + "subcategory": "", + "text": "Use managed vnet option if you have network isolation needs", + "description": "Managed virtual networks are virtual networks that are created and managed by Microsoft Fabric for each Fabric workspace. Managed virtual networks provide network isolation for Fabric Spark workloads, meaning that the compute clusters are deployed in a dedicated network and are no longer part of the shared virtual network. It is only supported for spark workload in Fabric.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "id": "F01.02", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview" + }, + { + "category": "Network Security", + "subcategory": "", + "text": "Use managed vnet IR to restrict the access over public internet for Azure Integration Runtime", + "description": "When you create an Azure integration runtime within a Data Factory managed virtual network, the integration runtime is provisioned with the managed virtual network. It uses private endpoints to securely connect to supported data stores.", + "waf": "Security", + "service": "Azure Data Factory", + "guid": "1193846d-697c-4c39-8ed1-6b2d186f0a12", + "id": "F01.03", + "severity": "Medium" + }, + { + "category": "Networking", + "subcategory": "", + "text": "Configure managed private endpoints to access Azure services", + "description": "Managed private endpoints are feature that allows secure and private access to data sources from Fabric Spark workloads. You cannot use starter pool with managed PE", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "id": "F01.03", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview" + }, + { + "category": "Network Security", + "subcategory": "", + "text": "Configure managed private endpoints to connect to resources using managed azure IR", + "description": "Managed private endpoints are private endpoints created in the Data Factory managed virtual network that establishes a private link to Azure resources. Data Factory manages these private endpoints on your behalf.", + "waf": "Security", + "service": "Azure Data Factory", + "guid": "41bddde6-8a47-47cd-bb48-61bc3bc10ae6", + "id": "F01.04", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/data-factory/managed-virtual-network-private-endpoint#managed-private-endpoints" + }, + { + "category": "Networking", + "subcategory": "", + "text": "Configure Private Links to access resources in your own Azure vnet i.e traffic coming in your Fabric environment", + "description": "Fabric uses a private IP address from your virtual network. The endpoint allows users in your network to communicate with Fabric over the private IP address using private links.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "id": "F01.04", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use" + }, + { + "category": "Networking", + "subcategory": "", + "text": "Configure Microsoft Entra ID conditional access if a user is trying to access your Fabric environment", + "description": "When a user authenticates access is determined based on a set of policies that might include IP address, location, and managed devices.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "id": "F01.05", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access" + }, + { + "category": "Networking", + "subcategory": "", + "text": "You can use Azure service tags to enable connections to and from Microsoft Fabric.", + "description": "In Azure, a service tag is a defined group of IP addresses that is automatically managed, as a group, to minimize the complexity of updates or changes to network security rules.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "id": "F01.06", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags" + }, + { + "category": "Networking", + "subcategory": "", + "text": "You can add Fabric URLs to your allowlist", + "description": "optional", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "id": "F01.07", + "severity": "Medium", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls" + }, + { + "category": "Networking", + "subcategory": "", + "text": "You can add Power BI URLs to your allowlist", + "description": "optional", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "id": "F01.08", + "severity": "Medium", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls" + }, + { + "category": "Networking", + "subcategory": "", + "text": "Configure and use On-prem data gateway or Vnet data gateway to connect to sources either on prem or behind a virtual network", + "description": "The data gateway lets you connect your Azure and other data services to Microsoft Fabric and the Power Platform to securely communicate with the data source, execute queries, and transmit results back to the service.", + "waf": "Security", + "service": "Microsoft Fabric", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "id": "F01.09", + "severity": "Medium", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install" + }, + { + "category": "", + "subcategory": "", + "text": "Configure Private Links to connect to sources in customer Vnet and data factory", + "description": "By using Azure Private Link, you can connect to various platform as a service (PaaS) deployments in Azure via a private endpoint. A private endpoint is a private IP address within a specific virtual network and subnet", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "service": "Azure Data Factory", + "waf": "Security", + "id": "G01.01", "severity": "Medium", "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link" }, @@ -749,402 +1143,7 @@ "id": "U01.02", "severity": "Medium", "link": "https://learn.microsoft.com/azure/databricks/security/network/classic/private-link" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Encrypt sensitive data in transit", - "description": "No additional configurations are required as this is enabled on a default deployment.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", - "id": "A01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Enable data at rest encryption by default", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", - "id": "A01.02", - "severity": "Medium" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Use customer-managed key option in data at rest encryption when required", - "description": "Use Keyvaults to store your CMK", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", - "id": "A01.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Use Microsoft Entra ID as the default authentication method and disable local access wherever possible", - "description": "Use Microsoft Entra ID as the default authentication method.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", - "id": "B01.01", - "severity": "High" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Use managed identity to authenticate to the services", - "description": "Use Microsoft Entra ID as the default authentication method.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", - "id": "B01.02", - "severity": "Medium" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Configure conditional access policies to restrict the access on Data plane", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", - "id": "B01.03", - "severity": "Medium" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Use Azure Key Vaults to store secrets and crendentials.", - "description": "Restrict exposure of keys and secerts", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", - "id": "B01.04", - "severity": "High" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Separate and limit highly privileged/administrative users", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", - "id": "B01.05", - "severity": "High" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Authenticate access to Event Hubs resources using shared access signatures (SAS) and restrict local users", - "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It�s recommended that you treat this rule like an administrative root account and don�t use it in your application. You can create additional policy rules in the Configure tab for the namespace in the portal, via PowerShell or Azure CLI. Avoid the usage of local authentication methods or accounts, these should be disabled wherever possible. Instead use Azure AD to authenticate where possible.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", - "id": "B01.06", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Use Azure RBACs to fine grain the access ", - "description": "Use Azure role-based access control (Azure RBAC) to manage Azure resource access through built-in role assignments. Azure RBAC roles can be assigned to users, groups, service principals, and managed identities.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", - "id": "B01.07", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Disable Public Network Access", - "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", - "id": "C01.01", - "severity": "Medium" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Use Vnets to isolate traffic over restricted network ", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", - "id": "C01.02", - "severity": "Medium" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Deploy private endpoints for all Azure resources that support the Private Link feature, to establish a private access point for the resources.", - "waf": "Security", - "service": "Azure Event Hubs", - "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", - "id": "C01.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Use Workspace roles to provide access to the users on the data", - "description": "Fabric controls data access using workspaces. In workspaces, data appears in the form of Fabric items, and users can't view or use items (data) unless you give them access to the workspace. You can find more information about workspace and item permissions, in Permission model.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", - "id": "D01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/fabric/security/permission-model" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Use RBAC on Onelake to provide fine grain access on the data in Tables/Files Onelake ", - "description": "OneLake RBAC uses role assignments to apply permissions to its members.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", - "id": "D01.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "When using shortcuts the user identity of the user should have access on the target location of the shortcut as well", - "description": "Take into account the access of the user at both target and source location of the shortcut", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", - "id": "D01.03", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Restrict providing workspace level role to users instead share an item only to the users", - "description": "Not all users need to have access on the entire workspace using roles so instead restrict giving roles on the entire workspace and only share the item to the user using share item feature or managing permission in Fabric", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", - "id": "D01.04", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "link": "https://learn.microsoft.com/fabric/get-started/share-items" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Limit access to the data by defining RLS, CLS and dynamic data masking on Warehouse and SQL analytics endpoints", - "description": "Use features like RLS, CLS and Dynamic data masking to enhance your data security requirements on sql workloads.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "5e401965-387e-45ce-b127-dd142b06b20c", - "id": "D01.05", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", - "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Limit access to the data by defining RLS and OLS on semantic models in Power BI", - "description": "Use features like RLS and OLS on Power BI to have more security features on semantic models", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", - "id": "D01.06", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Encrypt Data at rest", - "description": "In Fabric, all data that is stored in OneLake is encrypted at rest", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", - "id": "D01.07", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/" - }, - { - "category": "Data Protection", - "subcategory": "", - "text": "Encrypt data in transit", - "description": "Data in transit across the public internet between Microsoft services is always encrypted with at least TLS 1.2. Fabric negotiates to TLS 1.3 whenever possible.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", - "id": "D01.08", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Use Microsoft Entra ID as default authentication method", - "description": "No need to do anything. Every request to connect to Fabric is authenticated with Microsoft Entra ID, allowing users to safely connect to Fabric from their corporate office, when working at home, or from a remote location.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", - "id": "E01.01", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Use workspace identity to authenticate to the services", - "description": "A Fabric workspace identity is an automatically managed service principal that can be associated with a Fabric workspace. Workspace identities can be created in the workspace settings of any workspace except My workspaces. A workspace identity is automatically assigned the workspace contributor role and has access to workspace items. Limitation: Write to shortcut destination fails when using workspace identity as the authentication method. Connections with workspace-identity-authentication can only be used in Onelake shortcuts and data pipelines.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", - "id": "E01.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/fabric/security/workspace-identity" - }, - { - "category": "Identity and Access Management", - "subcategory": "", - "text": "Provide RBAC roles on storage account to the managed identity to make a successful connection", - "description": "Grant the identity permissions on the storage account", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", - "id": "E01.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Configure trusted workspace access to access storage account behind firewall ", - "description": "Fabric workspaces with a workspace identity can securely read or write to firewall-enabled Azure Data Lake Storage Gen2 accounts through�trusted workspace access�for OneLake shortcuts.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", - "id": "F01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Use managed vnet option if you have network isolation needs", - "description": "Managed virtual networks are virtual networks that are created and managed by Microsoft Fabric for each Fabric workspace. Managed virtual networks provide network isolation for Fabric Spark workloads, meaning that the compute clusters are deployed in a dedicated network and are no longer part of the shared virtual network. It is only supported for spark workload in Fabric.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", - "id": "F01.02", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Configure managed private endpoints to access Azure services", - "description": "Managed private endpoints are feature that allows secure and private access to data sources from Fabric Spark workloads. You cannot use starter pool with managed PE", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", - "id": "F01.03", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Configure Private Links to access resources in your own Azure vnet i.e traffic coming in your Fabric environment", - "description": "Fabric uses a private IP address from your virtual network. The endpoint allows users in your network to communicate with Fabric over the private IP address using private links.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", - "id": "F01.04", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "link": "https://learn.microsoft.com/fabric/security/security-private-links-use" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Configure Microsoft Entra ID conditional access if a user is trying to access your Fabric environment", - "description": "When a user authenticates access is determined based on a set of policies that might include IP address, location, and managed devices.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "6cb45e57-9603-4324-adf8-cc23318da611", - "id": "F01.05", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "link": "https://learn.microsoft.com/fabric/security/security-conditional-access" - }, - { - "category": "Networking", - "subcategory": "", - "text": "You can use Azure service tags to enable connections to and from Microsoft Fabric.", - "description": "In Azure, a service tag is a defined group of IP addresses that is automatically managed, as a group, to minimize the complexity of updates or changes to network security rules.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "70265f4b-b46a-4393-af70-317294797b15", - "id": "F01.06", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", - "link": "https://learn.microsoft.com/fabric/security/security-service-tags" - }, - { - "category": "Networking", - "subcategory": "", - "text": "You can add Fabric URLs to your allowlist", - "description": "optional", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "78a219a4-6beb-4544-9502-4922634292bb", - "id": "F01.07", - "severity": "Medium", - "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", - "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls" - }, - { - "category": "Networking", - "subcategory": "", - "text": "You can add Power BI URLs to your allowlist", - "description": "optional", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", - "id": "F01.08", - "severity": "Medium", - "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", - "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls" - }, - { - "category": "Networking", - "subcategory": "", - "text": "Configure and use On-prem data gateway or Vnet data gateway to connect to sources either on prem or behind a virtual network", - "description": "The data gateway lets you connect your Azure and other data services to Microsoft Fabric and the Power Platform to securely communicate with the data source, execute queries, and transmit results back to the service.", - "waf": "Security", - "service": "Microsoft Fabric", - "guid": "56cc071a-e9b1-441a-a889-535e727897e7", - "id": "F01.09", - "severity": "Medium", - "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install" - } - + } ], "categories": [], "waf": [ @@ -1209,6 +1208,6 @@ "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": "Preview", "waf": "Security", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" } -} +} \ No newline at end of file diff --git a/checklists/datasecurity_checklist.es.json b/checklists/datasecurity_checklist.es.json index eb1812e8..72812cce 100644 --- a/checklists/datasecurity_checklist.es.json +++ b/checklists/datasecurity_checklist.es.json @@ -12,6 +12,18 @@ "text": "Restringir el uso de usuarios locales en cargas de trabajo de SQL en Synapse", "waf": "Seguridad" }, + { + "category": "Protección de datos", + "description": "No se requieren configuraciones adicionales, ya que esto está habilitado en una implementación predeterminada.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Cifrar datos confidenciales en tránsito", + "waf": "Seguridad" + }, { "category": "Gestión de identidades y accesos", "description": "Use el identificador de Microsoft Entra como método de autenticación predeterminado para controlar el acceso al plano de datos.", @@ -24,6 +36,16 @@ "text": "Uso de la identidad administrada para autenticarse en los servicios", "waf": "Seguridad" }, + { + "category": "Protección de datos", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "id": "A01.02", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Habilitar el cifrado de datos en reposo de forma predeterminada", + "waf": "Seguridad" + }, { "category": "Gestión de identidades y accesos", "description": "Si no es necesario para las operaciones administrativas rutinarias, deshabilite o restrinja las cuentas de administrador local solo para uso de emergencia.", @@ -35,6 +57,18 @@ "text": "Separe y limite los usuarios administrativos o con muchos privilegios y habilite las directivas condicionales y de MFA", "waf": "Seguridad" }, + { + "category": "Protección de datos", + "description": "Uso de almacenes de claves para almacenar la CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Usar la opción de clave administrada por el cliente en el cifrado de datos en reposo cuando sea necesario", + "waf": "Seguridad" + }, { "category": "Gestión de identidades y accesos", "description": "Azure Synapse también incluye roles de control de acceso basado en roles (RBAC) de Synapse para administrar diferentes aspectos de Synapse Studio. Aproveche estos roles integrados para asignar permisos a usuarios, grupos u otras entidades de seguridad para administrar quién puede publicar artefactos de código y enumerar o acceder a artefactos de código publicados,Ejecutar código en grupos de Apache Spark y entornos de ejecución de integración,Acceder a servicios vinculados (datos) protegidos por credenciales,Supervisar o cancelar ejecuciones de trabajos, revisar la salida de trabajos y los registros de ejecución.", @@ -70,6 +104,17 @@ "text": "Uso del área de trabajo de red virtual administrada para restringir el acceso a través de la red pública de Internet", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "description": "Use el identificador de Microsoft Entra como método de autenticación predeterminado.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "id": "B01.01", + "service": "Azure Event Hubs", + "severity": "Alto", + "subcategory": "", + "text": "Use el identificador de Microsoft Entra como método de autenticación predeterminado y deshabilite el acceso local siempre que sea posible", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "description": "Para proteger los datos confidenciales, se recomienda deshabilitar por completo el acceso público a los puntos de conexión del área de trabajo. Al hacerlo, garantiza que solo se pueda acceder a todos los puntos de conexión del área de trabajo mediante puntos de conexión privados.", @@ -82,6 +127,17 @@ "text": "Configurar puntos de conexión privados para conectarse a los servicios externos y deshabilitar el acceso público", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "description": "Use el identificador de Microsoft Entra como método de autenticación predeterminado.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "id": "B01.02", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Uso de la identidad administrada para autenticarse en los servicios", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "description": "Si es necesario habilitar el acceso público, se recomienda encarecidamente configurar las reglas de firewall de IP para permitir conexiones entrantes solo desde la lista especificada de direcciones IP públicas.", @@ -93,6 +149,16 @@ "text": "Si se habilita el acceso público, se recomienda encarecidamente configurar las reglas de firewall de IP", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "id": "B01.03", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Configuración de directivas de acceso condicional para restringir el acceso en el plano de datos", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "guid": "d234292b-7528-4537-a551-c5bf4e4f1854", @@ -104,6 +170,17 @@ "text": "Implemente máquinas virtuales SHIR en la red virtual si trabaja con datos confidenciales que no deben salir de la red corporativa", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "description": "Restringir la exposición de claves y seguridades", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "B01.04", + "service": "Azure Event Hubs", + "severity": "Alto", + "subcategory": "", + "text": "Use Azure Key Vaults para almacenar secretos y créditos.", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "description": "Esto solo se puede hacer cuando se implementa el área de trabajo, pero las bibliotecas de Python instaladas desde repositorios públicos como PyPI no son compatibles. (Piense en la limitación antes de habilitarlo)", @@ -116,6 +193,40 @@ "text": "Habilitar la protección de exfiltración de datos (DEP)", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "id": "B01.05", + "service": "Azure Event Hubs", + "severity": "Alto", + "subcategory": "", + "text": "Separe y limite los usuarios con muchos privilegios/administrativos", + "waf": "Seguridad" + }, + { + "category": "Gestión de identidades y accesos", + "description": "Al crear un espacio de nombres de Event Hubs, se crea automáticamente una regla de directiva denominada RootManageSharedAccessKey para el espacio de nombres. Esta política tiene permisos de administración para todo el espacio de nombres. Se recomienda tratar esta regla como una cuenta raíz administrativa y no usarla en la aplicación. Puede crear reglas de directiva adicionales en la pestaña Configurar para el espacio de nombres en el portal, a través de PowerShell o la CLI de Azure. Evite el uso de métodos o cuentas de autenticación locales, estos deben deshabilitarse siempre que sea posible. En su lugar, use Azure AD para autenticarse siempre que sea posible.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Autenticar el acceso a los recursos de Event Hubs mediante firmas de acceso compartido (SAS) y restringir a los usuarios locales", + "waf": "Seguridad" + }, + { + "category": "Gestión de identidades y accesos", + "description": "Use el control de acceso basado en roles de Azure (RBAC de Azure) para administrar el acceso a los recursos de Azure a través de asignaciones de roles integradas. Los roles de RBAC de Azure se pueden asignar a usuarios, grupos, entidades de servicio e identidades administradas.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "id": "B01.07", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Uso de RBAC de Azure para precisar el acceso ", + "waf": "Seguridad" + }, { "category": "Protección de datos", "description": "La primera capa de cifrado la realizan las claves administradas por Microsoft, puede agregar una segunda capa de cifrado mediante claves administradas por el cliente", @@ -128,6 +239,17 @@ "text": "Cifrado de datos en reposo mediante claves administradas por el cliente para el área de trabajo", "waf": "Seguridad" }, + { + "category": "Gestión de redes", + "description": "El servicio admite la deshabilitación del acceso a la red pública mediante el uso de una regla de filtrado de ACL de IP de nivel de servicio (no NSG ni Azure Firewall) o mediante un conmutador de alternancia \"Deshabilitar el acceso a la red pública\".", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "id": "C01.01", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Desactivar el acceso a la red pública", + "waf": "Seguridad" + }, { "category": "Protección de datos", "description": "Azure Synapse aprovecha TLS para garantizar que los datos se cifran en movimiento. Los grupos dedicados de SQL admiten las versiones TLS 1.0, TLS 1.1 y TLS 1.2 para el cifrado, en los que los controladores proporcionados por Microsoft usan TLS 1.2 de forma predeterminada. El grupo de SQL sin servidor y el grupo de Apache Spark usan TLS 1.2 para todas las conexiones de salida.", @@ -140,6 +262,16 @@ "text": "Cifrado de datos en tránsito ", "waf": "Seguridad" }, + { + "category": "Gestión de redes", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "id": "C01.02", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Uso de redes virtuales para aislar el tráfico a través de una red restringida ", + "waf": "Seguridad" + }, { "category": "Protección de datos", "description": "Uso de Keyvaults para almacenar sus secretos y credenciales", @@ -151,15 +283,128 @@ "text": "Almacenamiento de contraseñas, seguridades y claves en Azure Key Vault", "waf": "Seguridad" }, + { + "category": "Gestión de redes", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "Medio", + "subcategory": "", + "text": "Implemente puntos de conexión privados para todos los recursos de Azure que admitan la característica Private Link para establecer un punto de acceso privado para los recursos.", + "waf": "Seguridad" + }, { "category": "", "description": "Puede almacenar credenciales o valores secretos en una instancia de Azure Key Vault y usarlos durante la ejecución de la canalización para pasarlos a sus actividades.", "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", "id": "D01.01", "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "Medio", + "subcategory": "", + "text": "Uso de secretos de Azure Key Vault en actividades de canalización", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "Fabric controla el acceso a los datos mediante espacios de trabajo. En los espacios de trabajo, los datos aparecen en forma de elementos de tejido y los usuarios no pueden ver ni usar elementos (datos) a menos que les conceda acceso al espacio de trabajo. Puede encontrar más información sobre los permisos del área de trabajo y los elementos en Modelo de permisos.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "id": "D01.01", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Utilice las funciones del área de trabajo para proporcionar acceso a los usuarios en los datos", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "RBAC de OneLake usa asignaciones de roles para aplicar permisos a sus miembros.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "id": "D01.02", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Utilice RBAC en Onelake para proporcionar acceso detallado a los datos en Tablas/Archivos Onelake ", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "Tenga en cuenta el acceso del usuario tanto en la ubicación de destino como en la de origen del acceso directo", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "id": "D01.03", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Al usar accesos directos, la identidad del usuario también debe tener acceso en la ubicación de destino del acceso directo", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "No todos los usuarios necesitan tener acceso a todo el espacio de trabajo mediante roles, por lo tanto, restrinja la asignación de roles en todo el espacio de trabajo y solo comparta el elemento con el usuario mediante la función de compartir elemento o el permiso de administración en Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "id": "D01.04", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Restrinja el suministro de roles de nivel de área de trabajo a los usuarios en lugar de compartir un elemento solo con los usuarios", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "Utilice características como RLS, CLS y enmascaramiento dinámico de datos para mejorar los requisitos de seguridad de datos en cargas de trabajo SQL.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "id": "D01.05", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", "severity": "Medio", "subcategory": "", - "text": "Uso de secretos de Azure Key Vault en actividades de canalización" + "text": "Limite el acceso a los datos mediante la definición de RLS, CLS y enmascaramiento de datos dinámicos en los puntos de conexión de análisis de SQL y Warehouse", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "Use características como RLS y OLS en Power BI para tener más características de seguridad en los modelos semánticos", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "id": "D01.06", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Limite el acceso a los datos definiendo RLS y OLS en modelos semánticos en Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "En Fabric, todos los datos que se almacenan en OneLake se cifran en reposo", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "id": "D01.07", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Cifrar datos en reposo", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Seguridad" + }, + { + "category": "Protección de datos", + "description": "Los datos en tránsito a través de la red pública de Internet entre los servicios de Microsoft siempre se cifran con al menos TLS 1.2. Fabric negocia con TLS 1.3 siempre que sea posible.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "id": "D01.08", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Cifrar datos en tránsito", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", @@ -172,6 +417,18 @@ "text": "Restrinja el uso de usuarios locales siempre que sea necesario", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "description": "No hay necesidad de hacer nada. Cada solicitud para conectarse a Fabric se autentica con Microsoft Entra ID, lo que permite a los usuarios conectarse de forma segura a Fabric desde su oficina corporativa, cuando trabajan en casa o desde una ubicación remota.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "id": "E01.01", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Usar el identificador de Microsoft Entra como método de autenticación predeterminado", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Seguridad" + }, { "category": "Gestión de identidades y accesos", "description": "Las identidades administradas eliminan la necesidad de administrar credenciales. Las identidades administradas proporcionan una identidad para la instancia de servicio al conectarse a recursos que admiten la autenticación de Microsoft Entra.", @@ -184,6 +441,18 @@ "text": "Uso de la identidad administrada para autenticarse en los servicios", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "description": "Una identidad de área de trabajo de Fabric es una entidad de servicio administrada automáticamente que se puede asociar a un área de trabajo de Fabric. Las identidades del área de trabajo se pueden crear en la configuración del área de trabajo de cualquier área de trabajo, excepto Mis áreas de trabajo. A una identidad de área de trabajo se le asigna automáticamente el rol de colaborador del área de trabajo y tiene acceso a los elementos del área de trabajo. Limitación: Se produce un error al escribir en el destino del acceso directo cuando se utiliza la identidad del área de trabajo como método de autenticación. Las conexiones con workspace-identity-authentication solo se pueden usar en accesos directos y canalizaciones de datos de Onelake.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "id": "E01.02", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Usar la identidad del área de trabajo para autenticarse en los servicios", + "waf": "Seguridad" + }, { "category": "Gestión de identidades y accesos", "description": "Si no es necesario para las operaciones administrativas rutinarias, deshabilite o restrinja las cuentas de administrador local solo para uso de emergencia.", @@ -195,6 +464,18 @@ "text": "Separe y limite los usuarios administrativos o con muchos privilegios y habilite las directivas condicionales y de MFA", "waf": "Seguridad" }, + { + "category": "Gestión de identidades y accesos", + "description": "Concesión de permisos de identidad en la cuenta de almacenamiento", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "id": "E01.03", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Proporcionar roles RBAC en la cuenta de almacenamiento a la identidad administrada para establecer una conexión correcta", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", @@ -202,7 +483,20 @@ "service": "Azure Data Factory", "severity": "Medio", "subcategory": "", - "text": "Deshabilite el acceso a través de Internet público y configure las reglas de firewall o las reglas de servicios de confianza" + "text": "Deshabilite el acceso a través de Internet público y configure las reglas de firewall o las reglas de servicios de confianza", + "waf": "Seguridad" + }, + { + "category": "Gestión de redes", + "description": "Las áreas de trabajo de Fabric con una identidad de área de trabajo pueden leer o escribir de forma segura en cuentas de Azure Data Lake Storage Gen2 habilitadas para firewall a través del acceso de confianza al área de trabajo para accesos directos de OneLake.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "id": "F01.01", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Configurar el acceso al área de trabajo de confianza para acceder a la cuenta de almacenamiento detrás del firewall ", + "waf": "Seguridad" }, { "category": "Seguridad de la red", @@ -214,6 +508,19 @@ "text": "Implemente máquinas virtuales SHIR en la red virtual si trabaja con datos confidenciales que no deben salir de la red corporativa", "waf": "Seguridad" }, + { + "category": "Gestión de redes", + "description": "Las redes virtuales administradas son redes virtuales creadas y administradas por Microsoft Fabric para cada área de trabajo de Fabric. Las redes virtuales administradas proporcionan aislamiento de red para las cargas de trabajo de Fabric Spark, lo que significa que los clústeres de proceso se implementan en una red dedicada y ya no forman parte de la red virtual compartida. Solo se admite para la carga de trabajo de Spark en Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "id": "F01.02", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Use la opción de red virtual administrada si tiene necesidades de aislamiento de red", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "description": "Al crear un entorno de ejecución de integración de Azure dentro de una red virtual administrada de Data Factory, el entorno de ejecución de integración se aprovisiona con la red virtual administrada. Utiliza puntos de conexión privados para conectarse de forma segura a los almacenes de datos compatibles.", @@ -225,6 +532,19 @@ "text": "Uso de IR de red virtual administrada para restringir el acceso a través de la red pública de Internet para Azure Integration Runtime", "waf": "Seguridad" }, + { + "category": "Gestión de redes", + "description": "Los puntos de conexión privados administrados son una característica que permite el acceso seguro y privado a los orígenes de datos de las cargas de trabajo de Fabric Spark. No se puede usar el grupo de inicio con PE administrado", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "id": "F01.03", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Configuración de puntos de conexión privados administrados para acceder a los servicios de Azure", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Seguridad" + }, { "category": "Seguridad de la red", "description": "Los puntos de conexión privados administrados son puntos de conexión privados creados en la red virtual administrada de Data Factory que establece un vínculo privado a los recursos de Azure. Data Factory administra estos puntos de conexión privados en su nombre.", @@ -237,15 +557,94 @@ "text": "Configuración de puntos de conexión privados administrados para conectarse a recursos mediante Azure IR administrado", "waf": "Seguridad" }, + { + "category": "Gestión de redes", + "description": "Fabric usa una dirección IP privada de la red virtual. El punto de conexión permite a los usuarios de la red comunicarse con Fabric a través de la dirección IP privada mediante enlaces privados.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "id": "F01.04", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Configure Private Links para acceder a los recursos de su propia red virtual de Azure, es decir, al tráfico que entra en su entorno de Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Seguridad" + }, + { + "category": "Gestión de redes", + "description": "El momento en que un usuario se autentica, el acceso se determina en función de un conjunto de directivas que pueden incluir la dirección IP, la ubicación y los dispositivos administrados.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "id": "F01.05", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Configurar el acceso condicional de ID de Microsoft Entra si un usuario intenta acceder a su entorno de Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Seguridad" + }, + { + "category": "Gestión de redes", + "description": "En Azure, una etiqueta de servicio es un grupo definido de direcciones IP que se administra automáticamente, como un grupo, para minimizar la complejidad de las actualizaciones o los cambios en las reglas de seguridad de red.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "id": "F01.06", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Puede usar etiquetas de servicio de Azure para habilitar las conexiones hacia y desde Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Seguridad" + }, + { + "category": "Gestión de redes", + "description": "opcional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "id": "F01.07", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Puedes agregar URL de Fabric a tu lista de permitidos", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Seguridad" + }, + { + "category": "Gestión de redes", + "description": "opcional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "id": "F01.08", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Puede agregar direcciones URL de Power BI a la lista de permitidos", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Seguridad" + }, + { + "category": "Gestión de redes", + "description": "La puerta de enlace de datos le permite conectar Azure y otros servicios de datos a Microsoft Fabric y Power Platform para comunicarse de forma segura con el origen de datos, ejecutar consultas y transmitir los resultados al servicio.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "id": "F01.09", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "Medio", + "subcategory": "", + "text": "Configure y use la puerta de enlace de datos local o la puerta de enlace de datos de red virtual para conectarse a orígenes locales o detrás de una red virtual", + "waf": "Seguridad" + }, { "category": "", "description": "Con Azure Private Link, puede conectarse a varias implementaciones de plataforma como servicio (PaaS) en Azure a través de un punto de conexión privado. Un punto de conexión privado es una dirección IP privada dentro de una red virtual y una subred específicas", "guid": "b47a393a-0804-4272-a479-8b1578b219a4", "id": "G01.01", "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", "severity": "Medio", "subcategory": "", - "text": "Configuración de vínculos privados para conectarse a orígenes en la red virtual del cliente y la factoría de datos" + "text": "Configuración de vínculos privados para conectarse a orígenes en la red virtual del cliente y la factoría de datos", + "waf": "Seguridad" }, { "category": "Protección de datos", @@ -301,7 +700,8 @@ "service": "Azure Data Factory", "severity": "Medio", "subcategory": "", - "text": "Uso de secretos de Azure Key Vault en actividades de canalización" + "text": "Uso de secretos de Azure Key Vault en actividades de canalización", + "waf": "Seguridad" }, { "category": "Protección de datos", @@ -312,7 +712,8 @@ "service": "Azure Data Factory", "severity": "Medio", "subcategory": "", - "text": "Cifrado de credenciales para el entorno local mediante almacenes de datos SHIR en Azure Data Factory" + "text": "Cifrado de credenciales para el entorno local mediante almacenes de datos SHIR en Azure Data Factory", + "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", @@ -636,9 +1037,11 @@ "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", "id": "P01.01", "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", "severity": "Alto", "subcategory": "", - "text": "Restringir a los administradores del espacio de trabajo" + "text": "Restringir a los administradores del espacio de trabajo", + "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", @@ -657,7 +1060,8 @@ "id": "R01.01", "severity": "Alto", "subcategory": "", - "text": "Regenere/gire las teclas si las usa periódicamente" + "text": "Regenere/gire las teclas si las usa periódicamente", + "waf": "Seguridad" }, { "category": "Gestión de identidades y accesos", @@ -745,7 +1149,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": "Preview", - "timestamp": "October 21, 2024", + "timestamp": "October 23, 2024", "waf": "Security" }, "severities": [ diff --git a/checklists/datasecurity_checklist.ja.json b/checklists/datasecurity_checklist.ja.json index a8c87ff8..beacc1dd 100644 --- a/checklists/datasecurity_checklist.ja.json +++ b/checklists/datasecurity_checklist.ja.json @@ -12,6 +12,18 @@ "text": "Synapse 上の sql ワークロードでのローカル ユーザーの使用を制限する", "waf": "安全" }, + { + "category": "データ保護", + "description": "これはデフォルトのデプロイメントで有効になっているため、追加の構成は必要ありません。", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "転送中の機密データを暗号化する", + "waf": "安全" + }, { "category": "ID およびアクセス管理", "description": "Microsoft Entra ID を既定の認証方法として使用して、データ プレーン アクセスを制御します。", @@ -24,6 +36,16 @@ "text": "マネージド ID を使用してサービスに対して認証する", "waf": "安全" }, + { + "category": "データ保護", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "id": "A01.02", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "デフォルトで保存データの暗号化を有効にする", + "waf": "安全" + }, { "category": "ID およびアクセス管理", "description": "日常的な管理操作に必要ない場合は、緊急時のみの使用のためにローカル管理者アカウントを無効または制限します。", @@ -35,6 +57,18 @@ "text": "高い権限を持つユーザーや管理ユーザーを分離して制限し、MFAと条件付きポリシーを有効にする", "waf": "安全" }, + { + "category": "データ保護", + "description": "Keyvaults を使用して CMK を保存する", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "必要に応じて、保存データの暗号化でカスタマー マネージド キー オプションを使用する", + "waf": "安全" + }, { "category": "ID およびアクセス管理", "description": "Azure Synapse には、Synapse Studio のさまざまな側面を管理するための Synapse ロールベースのアクセス制御 (RBAC) ロールも含まれています。これらの組み込みロールを活用して、ユーザー、グループ、またはその他のセキュリティ プリンシパルにアクセス許可を割り当て、コード成果物の発行、公開されたコード成果物の一覧表示またはアクセス、Apache Spark プールと統合ランタイムでのコードの実行、資格情報で保護されているリンクされた (データ) サービスへのアクセス、ジョブ実行の監視またはキャンセル、ジョブ出力と実行ログの確認を行うことができます。", @@ -70,6 +104,17 @@ "text": "マネージド vnet ワークスペースを使用して、パブリック インターネット経由のアクセスを制限する", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "description": "デフォルトの認証方法として Microsoft Entra ID を使用します。", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "id": "B01.01", + "service": "Azure Event Hubs", + "severity": "高い", + "subcategory": "", + "text": "Microsoft Entra ID を既定の認証方法として使用し、可能な限りローカル アクセスを無効にします", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "description": "機密データを保護するために、ワークスペース エンドポイントへのパブリック アクセスを完全に無効にすることをお勧めします。これにより、すべてのワークスペース エンドポイントにプライベート エンドポイントを使用してのみアクセスできるようになります。", @@ -82,6 +127,17 @@ "text": "外部サービスに接続し、パブリックアクセスを無効にするようにプライベートエンドポイントを設定します", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "description": "デフォルトの認証方法として Microsoft Entra ID を使用します。", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "id": "B01.02", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "マネージド ID を使用してサービスに対して認証する", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "description": "パブリック アクセスを有効にする必要がある場合は、指定したパブリック IP アドレスの一覧からの受信接続のみを許可するように IP ファイアウォール規則を構成することを強くお勧めします。", @@ -93,6 +149,16 @@ "text": "パブリック アクセスを有効にする場合は、IP ファイアウォール ルールを構成することを強くお勧めします", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "id": "B01.03", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "条件付きアクセス ポリシーを構成して、データ プレーンでのアクセスを制限する", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "guid": "d234292b-7528-4537-a551-c5bf4e4f1854", @@ -104,6 +170,17 @@ "text": "企業ネットワークから離れるべきではない機密データを扱っている場合は、vnet に SHIR VM をデプロイします", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "description": "キーと secert の公開を制限する", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "B01.04", + "service": "Azure Event Hubs", + "severity": "高い", + "subcategory": "", + "text": "Azure Key Vault を使用して、シークレットと crendentials を格納します。", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "description": "これはワークスペースをデプロイするときにのみ実行できますが、PyPI などのパブリック リポジトリからインストールされた Python ライブラリはサポートされていません。(有効にする前に制限について考えてください)", @@ -116,6 +193,40 @@ "text": "データ流出防止 (DEP) を有効にする", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "id": "B01.05", + "service": "Azure Event Hubs", + "severity": "高い", + "subcategory": "", + "text": "高い権限を持つユーザーや管理ユーザーを分離して制限する", + "waf": "安全" + }, + { + "category": "ID およびアクセス管理", + "description": "Event Hubs 名前空間を作成すると、名前空間に対して RootManageSharedAccessKey という名前のポリシー ルールが自動的に作成されます。このポリシーには、名前空間全体に対する管理アクセス許可があります。このルールは管理ルート アカウントのように扱い、アプリケーションで使用しないことをお勧めします。ポータルの名前空間の [構成] タブで、PowerShell または Azure CLI を使用して追加のポリシー ルールを作成できます。ローカル認証方法やアカウントの使用は避け、可能な限り無効にする必要があります。代わりに、可能な場合は Azure AD を使用して認証します。", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "Shared Access Signature (SAS) を使用して Event Hubs リソースへのアクセスを認証し、ローカル ユーザーを制限する", + "waf": "安全" + }, + { + "category": "ID およびアクセス管理", + "description": "Azure ロールベースのアクセス制御 (Azure RBAC) を使用して、組み込みのロール割り当てを通じて Azure リソースへのアクセスを管理します。Azure RBAC ロールは、ユーザー、グループ、サービス プリンシパル、マネージド ID に割り当てることができます。", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "id": "B01.07", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "Azure RBAC を使用してアクセスをきめ細かくする", + "waf": "安全" + }, { "category": "データ保護", "description": "暗号化の最初のレイヤーは Microsoft マネージド キーによって行われますが、カスタマー マネージド キーを使用して 2 番目の暗号化レイヤーを追加できます", @@ -128,6 +239,17 @@ "text": "ワークスペースのカスタマー マネージド キーを使用した保存時のデータ暗号化", "waf": "安全" }, + { + "category": "ネットワーキング", + "description": "サービスでは、サービス レベルの IP ACL フィルタリング規則 (NSG や Azure Firewall ではない) を使用するか、\"パブリック ネットワーク アクセスを無効にする\" トグル スイッチを使用して、パブリック ネットワーク アクセスを無効にすることがサポートされています。", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "id": "C01.01", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "パブリックネットワークアクセスの無効化", + "waf": "安全" + }, { "category": "データ保護", "description": "Azure Synapse は TLS を利用して、移動中のデータが暗号化されるようにします。SQL 専用プールでは、暗号化のために TLS 1.0、TLS 1.1、TLS 1.2 バージョンがサポートされています。このバージョンでは、Microsoft が提供するドライバーでは既定で TLS 1.2 が使用されます。サーバーレス SQL プールと Apache Spark プールでは、すべての送信接続に TLS 1.2 が使用されます。", @@ -140,6 +262,16 @@ "text": "転送中のデータ暗号化", "waf": "安全" }, + { + "category": "ネットワーキング", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "id": "C01.02", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "Vnets を使用して、制限されたネットワーク上のトラフィックを分離する", + "waf": "安全" + }, { "category": "データ保護", "description": "Keyvaults を使用してシークレットと資格情報を格納する", @@ -151,15 +283,128 @@ "text": "パスワード、セキュリティ、キーを Azure Key Vault に格納する", "waf": "安全" }, + { + "category": "ネットワーキング", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "中程度", + "subcategory": "", + "text": "Private Link 機能をサポートするすべての Azure リソースにプライベート エンドポイントをデプロイして、リソースのプライベート アクセス ポイントを確立します。", + "waf": "安全" + }, { "category": "", "description": "資格情報またはシークレット値を Azure Key Vault に格納し、パイプラインの実行中にそれらを使用してアクティビティに渡すことができます。", "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", "id": "D01.01", "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "中程度", + "subcategory": "", + "text": "パイプライン アクティビティで Azure Key Vault シークレットを使用する", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "Fabric は、ワークスペースを使用してデータ アクセスを制御します。ワークスペースでは、データは Fabric アイテムの形式で表示され、ワークスペースへのアクセス権を付与しない限り、ユーザーはアイテム (データ) を表示または使用できません。ワークスペースとアイテムのアクセス許可の詳細については、「アクセス許可モデル」を参照してください。", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "id": "D01.01", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ワークスペース ロールを使用して、データに対するアクセス権をユーザーに付与します", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "OneLake RBAC は、ロールの割り当てを使用して、メンバーにアクセス許可を適用します。", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "id": "D01.02", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Onelake で RBAC を使用して、Onelake のテーブル/ファイル内のデータに対するきめ細かなアクセスを提供します", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "ショートカットのターゲットとソースの両方の場所でのユーザーのアクセスを考慮に入れます", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "id": "D01.03", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ショートカットを使用する場合、ユーザーのユーザー ID は、ショートカットのターゲットの場所にもアクセスできる必要があります", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "すべてのユーザーがロールを使用してワークスペース全体にアクセスする必要はないため、代わりにワークスペース全体でロールを付与することを制限し、アイテムの共有機能を使用するか、Fabric で権限を管理するユーザーのみにアイテムを共有します", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "id": "D01.04", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ワークスペース レベルのロールの提供をユーザーに制限し、代わりにアイテムをユーザーのみに共有します", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "RLS、CLS、ダイナミック データ マスキングなどの機能を使用して、SQL ワークロードのデータ セキュリティ要件を強化します。", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "id": "D01.05", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", "severity": "中程度", "subcategory": "", - "text": "パイプライン アクティビティで Azure Key Vault シークレットを使用する" + "text": "Warehouse と SQL 分析エンドポイントで RLS、CLS、動的データ マスキングを定義することで、データへのアクセスを制限します", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "Power BI で RLS や OLS などの機能を使用して、セマンティック モデルでより多くのセキュリティ機能を使用", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "id": "D01.06", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Power BI のセマンティック モデルで RLS と OLS を定義して、データへのアクセスを制限する", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "Fabric では、OneLake に格納されているすべてのデータは保存時に暗号化されます", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "id": "D01.07", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "保存データの暗号化", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "安全" + }, + { + "category": "データ保護", + "description": "Microsoft サービス間でパブリック インターネット経由で転送されるデータは、常に少なくとも TLS 1.2 で暗号化されます。Fabric は、可能な限り TLS 1.3 にネゴシエートします。", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "id": "D01.08", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "転送中のデータを暗号化する", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" }, { "category": "ID およびアクセス管理", @@ -172,6 +417,18 @@ "text": "必要に応じてローカルユーザーの使用を制限する", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "description": "何もする必要はありません。Fabric に接続するすべての要求は Microsoft Entra ID で認証されるため、ユーザーは会社のオフィスから、自宅での作業中、またはリモートの場所から Fabric に安全に接続できます。", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "id": "E01.01", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Microsoft Entra ID を既定の認証方法として使用する", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, { "category": "ID およびアクセス管理", "description": "マネージド ID を使用すると、資格情報を管理する必要がなくなります。マネージド ID は、Microsoft Entra 認証をサポートするリソースに接続するときに、サービス インスタンスの ID を提供します。", @@ -184,6 +441,18 @@ "text": "マネージド ID を使用してサービスに対して認証する", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "description": "Fabric ワークスペース ID は、Fabric ワークスペースに関連付けることができる、自動的に管理されるサービス プリンシパルです。ワークスペース ID は、 [マイ ワークスペース] を除く任意のワークスペースのワークスペース設定で作成できます。ワークスペース ID には、ワークスペース共同作成者ロールが自動的に割り当てられ、ワークスペース項目にアクセスできます。 制限事項: 認証方法としてワークスペース ID を使用すると、ショートカットの宛先への書き込みが失敗します。workspace-identity-authentication を使用した接続は、Onelake ショートカットとデータ パイプラインでのみ使用できます。", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "id": "E01.02", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ワークスペース ID を使用してサービスに対して認証する", + "waf": "安全" + }, { "category": "ID およびアクセス管理", "description": "日常的な管理操作に必要ない場合は、緊急時のみの使用のためにローカル管理者アカウントを無効または制限します。", @@ -195,6 +464,18 @@ "text": "高い権限を持つユーザーや管理ユーザーを分離して制限し、MFAと条件付きポリシーを有効にする", "waf": "安全" }, + { + "category": "ID およびアクセス管理", + "description": "ストレージ アカウントに対する ID のアクセス許可を付与する", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "id": "E01.03", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ストレージ アカウントの RBAC ロールをマネージド ID に指定して、接続を成功させます", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", @@ -202,7 +483,20 @@ "service": "Azure Data Factory", "severity": "中程度", "subcategory": "", - "text": "パブリックインターネット経由のアクセスを無効にし、ファイアウォールルールまたは信頼できるサービスルールのいずれかを設定します" + "text": "パブリックインターネット経由のアクセスを無効にし、ファイアウォールルールまたは信頼できるサービスルールのいずれかを設定します", + "waf": "安全" + }, + { + "category": "ネットワーキング", + "description": "ワークスペース ID を持つファブリック ワークスペースは、OneLake ショートカットの信頼されたワークスペース アクセスを通じて、ファイアウォール対応の Azure Data Lake Storage Gen2 アカウントに対して安全に読み取りまたは書き込みを行うことができます。", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "id": "F01.01", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ファイアウォールの内側にあるストレージ アカウントにアクセスするための信頼されたワークスペース アクセスを構成する", + "waf": "安全" }, { "category": "ネットワークセキュリティ", @@ -214,6 +508,19 @@ "text": "企業ネットワークから離れるべきではない機密データを扱っている場合は、vnet に SHIR VM をデプロイします", "waf": "安全" }, + { + "category": "ネットワーキング", + "description": "マネージド仮想ネットワークは、Microsoft Fabric によって各 Fabric ワークスペースに対して作成および管理される仮想ネットワークです。マネージド仮想ネットワークは、Fabric Spark ワークロードのネットワーク分離を提供するため、コンピューティング クラスターは専用ネットワークにデプロイされ、共有仮想ネットワークの一部ではなくなります。これは、Fabric の Spark ワークロードでのみサポートされます。", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "id": "F01.02", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ネットワーク分離が必要な場合は、managed vnet オプションを使用してください", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "description": "Data Factory マネージド仮想ネットワーク内に Azure 統合ランタイムを作成すると、統合ランタイムはマネージド仮想ネットワークと共にプロビジョニングされます。プライベート エンドポイントを使用して、サポートされているデータ ストアに安全に接続します。", @@ -225,6 +532,19 @@ "text": "マネージド vnet IR を使用して、Azure Integration Runtime のパブリック インターネット経由のアクセスを制限する", "waf": "安全" }, + { + "category": "ネットワーキング", + "description": "マネージド プライベート エンドポイントは、Fabric Spark ワークロードからデータ ソースへの安全でプライベートなアクセスを可能にする機能です。スターター・プールは、管理対象 PE では使用できません", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "id": "F01.03", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Azure サービスにアクセスするためのマネージド プライベート エンドポイントの構成", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, { "category": "ネットワークセキュリティ", "description": "マネージド プライベート エンドポイントは、Azure リソースへのプライベート リンクを確立する Data Factory マネージド仮想ネットワークで作成されたプライベート エンドポイントです。Data Factory は、ユーザーに代わってこれらのプライベート エンドポイントを管理します。", @@ -237,15 +557,94 @@ "text": "マネージド プライベート エンドポイントを構成して、マネージド Azure IR を使用してリソースに接続する", "waf": "安全" }, + { + "category": "ネットワーキング", + "description": "Fabric は、仮想ネットワークのプライベート IP アドレスを使用します。このエンドポイントにより、ネットワーク内のユーザーは、プライベートリンクを使用してプライベートIPアドレスを介してFabricと通信できます。", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "id": "F01.04", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Private Link を構成して、独自の Azure vnet 内のリソース (Fabric 環境に来るトラフィック) にアクセスします", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "category": "ネットワーキング", + "description": "ユーザーの認証を受けるタイミングは、IP アドレス、場所、管理対象デバイスなどの一連のポリシーに基づいて決定されます。", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "id": "F01.05", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "ユーザーが Fabric 環境にアクセスしようとしている場合に Microsoft Entra ID の条件付きアクセスを構成する", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "category": "ネットワーキング", + "description": "Azure では、サービス タグは定義された IP アドレスのグループであり、ネットワーク セキュリティ規則の更新や変更の複雑さを最小限に抑えるために、グループとして自動的に管理されます。", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "id": "F01.06", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Azure サービス タグを使用して、Microsoft Fabric との間の接続を有効にすることができます。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "安全" + }, + { + "category": "ネットワーキング", + "description": "随意", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "id": "F01.07", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Fabric URL を許可リストに追加できます", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "安全" + }, + { + "category": "ネットワーキング", + "description": "随意", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "id": "F01.08", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "Power BI の URL を許可リストに追加できます", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "安全" + }, + { + "category": "ネットワーキング", + "description": "データ ゲートウェイを使用すると、Azure やその他のデータ サービスを Microsoft Fabric と Power Platform に接続して、データ ソースと安全に通信し、クエリを実行し、結果をサービスに送信できます。", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "id": "F01.09", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "中程度", + "subcategory": "", + "text": "オンプレミス データ ゲートウェイまたは Vnet データ ゲートウェイを構成して使用し、オンプレミスまたは仮想ネットワークの背後にあるソースに接続する", + "waf": "安全" + }, { "category": "", "description": "Azure Private Link を使用すると、プライベート エンドポイントを介して Azure のさまざまなサービスとしてのプラットフォーム (PaaS) デプロイに接続できます。プライベート エンドポイントは、特定の仮想ネットワークとサブネット内のプライベート IP アドレスです", "guid": "b47a393a-0804-4272-a479-8b1578b219a4", "id": "G01.01", "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", "severity": "中程度", "subcategory": "", - "text": "顧客の Vnet とデータ ファクトリのソースに接続するように Private Link を構成する" + "text": "顧客の Vnet とデータ ファクトリのソースに接続するように Private Link を構成する", + "waf": "安全" }, { "category": "データ保護", @@ -301,7 +700,8 @@ "service": "Azure Data Factory", "severity": "中程度", "subcategory": "", - "text": "パイプライン アクティビティで Azure Key Vault シークレットを使用する" + "text": "パイプライン アクティビティで Azure Key Vault シークレットを使用する", + "waf": "安全" }, { "category": "データ保護", @@ -312,7 +712,8 @@ "service": "Azure Data Factory", "severity": "中程度", "subcategory": "", - "text": "Azure Data Factory の SHIR データ ストアを使用してオンプレミスの資格情報を暗号化する" + "text": "Azure Data Factory の SHIR データ ストアを使用してオンプレミスの資格情報を暗号化する", + "waf": "安全" }, { "category": "ID およびアクセス管理", @@ -636,9 +1037,11 @@ "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", "id": "P01.01", "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", "severity": "高い", "subcategory": "", - "text": "ワークスペース管理者を制限する" + "text": "ワークスペース管理者を制限する", + "waf": "安全" }, { "category": "ID およびアクセス管理", @@ -657,7 +1060,8 @@ "id": "R01.01", "severity": "高い", "subcategory": "", - "text": "キーを定期的に使用する場合は、キーを再生成/ローテーションします" + "text": "キーを定期的に使用する場合は、キーを再生成/ローテーションします", + "waf": "安全" }, { "category": "ID およびアクセス管理", @@ -745,7 +1149,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": "Preview", - "timestamp": "October 21, 2024", + "timestamp": "October 23, 2024", "waf": "Security" }, "severities": [ diff --git a/checklists/datasecurity_checklist.ko.json b/checklists/datasecurity_checklist.ko.json index 6788bac1..f4520ed2 100644 --- a/checklists/datasecurity_checklist.ko.json +++ b/checklists/datasecurity_checklist.ko.json @@ -12,6 +12,18 @@ "text": "Synapse의 SQL 워크로드에서 로컬 사용자 사용 제한", "waf": "안전" }, + { + "category": "데이터 보호", + "description": "기본 배포에서 사용하도록 설정되므로 추가 구성이 필요하지 않습니다.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "전송 중인 민감한 데이터 암호화", + "waf": "안전" + }, { "category": "ID 및 액세스 관리", "description": "Microsoft Entra ID를 기본 인증 방법으로 사용하여 데이터 평면 액세스를 제어합니다.", @@ -24,6 +36,16 @@ "text": "관리 ID를 사용하여 서비스에 인증", "waf": "안전" }, + { + "category": "데이터 보호", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "id": "A01.02", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "기본적으로 미사용 데이터 암호화 사용Enable data at rest encryption by default", + "waf": "안전" + }, { "category": "ID 및 액세스 관리", "description": "일상적인 관리 작업에 필요하지 않은 경우 긴급 용도로만 로컬 관리자 계정을 사용하지 않도록 설정하거나 제한합니다.", @@ -35,6 +57,18 @@ "text": "높은 권한이 부여된/관리 사용자를 분리 및 제한하고 MFA 및 조건부 정책을 사용하도록 설정합니다.", "waf": "안전" }, + { + "category": "데이터 보호", + "description": "Keyvaults를 사용하여 CMK 저장", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "필요한 경우 미사용 데이터 암호화에서 고객 관리형 키 옵션을 사용합니다.", + "waf": "안전" + }, { "category": "ID 및 액세스 관리", "description": "Azure Synapse에는 Synapse Studio의 다양한 측면을 관리하기 위한 Synapse RBAC(역할 기반 액세스 제어) 역할도 포함되어 있습니다. 이러한 기본 제공 역할을 활용하여 사용자, 그룹 또는 기타 보안 주체에 권한을 할당하여 코드 아티팩트를 게시하고, 게시된 코드 아티팩트를 나열하거나 액세스할 수 있는 사용자를 관리하고, Apache Spark 풀 및 통합 런타임에서 코드를 실행하고, 자격 증명으로 보호되는 연결된(데이터) 서비스에 액세스하고, 작업 실행을 모니터링 또는 취소하고, 작업 출력 및 실행 로그를 검토합니다.", @@ -70,6 +104,17 @@ "text": "관리되는 vnet 작업 영역을 사용하여 공용 인터넷을 통한 액세스 제한", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "description": "Microsoft Entra ID를 기본 인증 방법으로 사용합니다.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "id": "B01.01", + "service": "Azure Event Hubs", + "severity": "높다", + "subcategory": "", + "text": "Microsoft Entra ID를 기본 인증 방법으로 사용하고 가능한 경우 로컬 액세스를 사용하지 않도록 설정합니다.", + "waf": "안전" + }, { "category": "네트워크 보안", "description": "중요한 데이터를 보호하려면 작업 영역 엔드포인트에 대한 공용 액세스를 완전히 사용하지 않도록 설정하는 것이 좋습니다. 이렇게 하면 프라이빗 엔드포인트를 통해서만 모든 작업 영역 엔드포인트에 액세스할 수 있습니다.", @@ -82,6 +127,17 @@ "text": "외부 서비스에 연결하고 공용 액세스를 사용하지 않도록 프라이빗 엔드포인트를 구성합니다.", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "description": "Microsoft Entra ID를 기본 인증 방법으로 사용합니다.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "id": "B01.02", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "관리 ID를 사용하여 서비스에 인증", + "waf": "안전" + }, { "category": "네트워크 보안", "description": "공용 액세스를 사용하도록 설정해야 하는 경우 지정된 공용 IP 주소 목록에서만 인바운드 연결을 허용하도록 IP 방화벽 규칙을 구성하는 것이 좋습니다.", @@ -93,6 +149,16 @@ "text": "공용 액세스를 사용하도록 설정하는 경우 IP 방화벽 규칙을 구성하는 것이 좋습니다.", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "id": "B01.03", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "데이터 플레인에 대한 액세스를 제한하는 조건부 액세스 정책 구성Configure conditional access policies to restrict access on the Data plane", + "waf": "안전" + }, { "category": "네트워크 보안", "guid": "d234292b-7528-4537-a551-c5bf4e4f1854", @@ -104,6 +170,17 @@ "text": "회사 네트워크를 벗어나지 않아야 하는 중요한 데이터로 작업하는 경우 VN에 SHIR VM을 배포합니다.", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "description": "키 및 인증서 노출 제한", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "B01.04", + "service": "Azure Event Hubs", + "severity": "높다", + "subcategory": "", + "text": "Azure Key Vault를 사용하여 비밀 및 크레센셜을 저장합니다.", + "waf": "안전" + }, { "category": "네트워크 보안", "description": "이 작업은 작업 영역을 배포할 때만 수행할 수 있지만 PyPI와 같은 공용 리포지토리에서 설치된 Python 라이브러리는 지원되지 않습니다. (활성화하기 전에 제한 사항에 대해 생각하십시오)", @@ -116,6 +193,40 @@ "text": "DEP(데이터 반출 보호) 사용", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "id": "B01.05", + "service": "Azure Event Hubs", + "severity": "높다", + "subcategory": "", + "text": "높은 권한이 있는 사용자/관리 사용자 분리 및 제한", + "waf": "안전" + }, + { + "category": "ID 및 액세스 관리", + "description": "Event Hubs 네임스페이스를 만들면 네임스페이스에 대해 RootManageSharedAccessKey라는 정책 규칙이 자동으로 만들어집니다. 이 정책에는 전체 네임스페이스에 대한 관리 권한이 있습니다. 이 규칙을 관리 루트 계정처럼 취급하고 응용 프로그램에서 사용하지 않는 것이 좋습니다. PowerShell 또는 Azure CLI를 통해 포털의 네임스페이스에 대한 구성 탭에서 추가 정책 규칙을 만들 수 있습니다. 로컬 인증 방법 또는 계정을 사용하지 말고 가능한 한 사용하지 않도록 설정해야 합니다. 대신 가능한 경우 Azure AD를 사용하여 인증합니다.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "SAS(공유 액세스 서명)를 사용하여 Event Hubs 리소스에 대한 액세스를 인증하고 로컬 사용자를 제한합니다.", + "waf": "안전" + }, + { + "category": "ID 및 액세스 관리", + "description": "Azure RBAC(Azure 역할 기반 액세스 제어)를 사용하여 기본 제공 역할 할당을 통해 Azure 리소스 액세스를 관리합니다. Azure RBAC 역할은 사용자, 그룹, 서비스 주체 및 관리 ID에 할당할 수 있습니다.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "id": "B01.07", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "Azure RBAC를 사용하여 액세스 세분화 ", + "waf": "안전" + }, { "category": "데이터 보호", "description": "첫 번째 암호화 계층은 Microsoft 관리형 키에 의해 수행되며, 고객 관리형 키를 사용하여 두 번째 암호화 계층을 추가할 수 있습니다", @@ -128,6 +239,17 @@ "text": "작업 영역에 대한 고객 관리형 키를 사용한 미사용 데이터 암호화Data Encryption at rest using Customer managed Keys for workspace", "waf": "안전" }, + { + "category": "네트워킹", + "description": "서비스는 서비스 수준 IP ACL 필터링 규칙(NSG 또는 Azure Firewall 아님)을 사용하거나 '공용 네트워크 액세스 사용 안 함' 토글 스위치를 사용하여 공용 네트워크 액세스를 사용하지 않도록 설정할 수 있도록 지원합니다.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "id": "C01.01", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "공용 네트워크 액세스 사용 안 함", + "waf": "안전" + }, { "category": "데이터 보호", "description": "Azure Synapse는 TLS를 활용하여 이동 중인 데이터가 암호화되도록 합니다. SQL 전용 풀은 암호화를 위해 TLS 1.0, TLS 1.1 및 TLS 1.2 버전을 지원하며, Microsoft에서 제공하는 드라이버는 기본적으로 TLS 1.2를 사용합니다. 서버리스 SQL 풀 및 Apache Spark 풀은 모든 아웃바운드 연결에 TLS 1.2를 사용합니다.", @@ -140,6 +262,16 @@ "text": "전송 중 데이터 암호화 ", "waf": "안전" }, + { + "category": "네트워킹", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "id": "C01.02", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "Vnet을 사용하여 제한된 네트워크를 통한 트래픽 격리 ", + "waf": "안전" + }, { "category": "데이터 보호", "description": "Keyvaults를 사용하여 비밀 및 자격 증명 저장", @@ -151,15 +283,128 @@ "text": "Azure Key Vault에 암호, secerts 및 키 저장Store passwords, secerts and keys in Azure key vault", "waf": "안전" }, + { + "category": "네트워킹", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "보통", + "subcategory": "", + "text": "Private Link 기능을 지원하는 모든 Azure 리소스에 대한 프라이빗 엔드포인트를 배포하여 리소스에 대한 프라이빗 액세스 지점을 설정합니다.", + "waf": "안전" + }, { "category": "", "description": "Azure Key Vault에 자격 증명 또는 비밀 값을 저장하고 파이프라인 실행 중에 사용하여 활동에 전달할 수 있습니다.", "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", "id": "D01.01", "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "보통", + "subcategory": "", + "text": "파이프라인 활동에서 Azure Key Vault 비밀 사용Use Azure Key Vault secrets in pipeline activities", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "Fabric은 작업 영역을 사용하여 데이터 액세스를 제어합니다. 작업공간에서 데이터는 패브릭 항목의 형태로 표시되며, 사용자는 작업공간에 대한 액세스 권한을 부여하지 않는 한 항목(데이터)을 보거나 사용할 수 없습니다. 작업 영역 및 항목 권한에 대한 자세한 내용은 사용 권한 모델에서 확인할 수 있습니다.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "id": "D01.01", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "작업 영역 역할을 사용하여 사용자에게 데이터에 대한 액세스 권한 제공", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "OneLake RBAC는 역할 할당을 사용하여 구성원에게 권한을 적용합니다.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "id": "D01.02", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "Onelake에서 RBAC를 사용하여 테이블/파일 Onelake의 데이터에 대한 세분화된 액세스를 제공합니다. ", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "바로 가기의 대상 위치와 원본 위치 모두에서 사용자의 액세스를 고려합니다.", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "id": "D01.03", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "바로 가기를 사용하는 경우 사용자의 사용자 ID는 바로 가기의 대상 위치에도 액세스할 수 있어야 합니다", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "모든 사용자가 역할을 사용하여 전체 워크스페이스에 액세스할 필요가 있는 것은 아니므로 대신 전체 워크스페이스에 대한 역할 부여를 제한하고 항목 공유 기능 또는 Fabric의 관리 권한을 사용하여 사용자에게만 항목을 공유합니다.", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "id": "D01.04", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "작업 영역 수준 역할을 사용자에게 제공하는 것을 제한하는 대신 사용자에게만 항목을 공유합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "RLS, CLS 및 동적 데이터 마스킹과 같은 기능을 사용하여 SQL 워크로드에 대한 데이터 보안 요구 사항을 강화합니다.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "id": "D01.05", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", "severity": "보통", "subcategory": "", - "text": "파이프라인 활동에서 Azure Key Vault 비밀 사용Use Azure Key Vault secrets in pipeline activities" + "text": "웨어하우스 및 SQL 분석 엔드포인트에서 RLS, CLS 및 동적 데이터 마스킹을 정의하여 데이터에 대한 액세스를 제한합니다.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "Power BI에서 RLS 및 OLS와 같은 기능을 사용하여 의미 체계 모델에 더 많은 보안 기능을 사용할 수 있습니다.", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "id": "D01.06", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "Power BI의 의미 체계 모델에서 RLS 및 OLS를 정의하여 데이터에 대한 액세스를 제한합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "Fabric에서 OneLake에 저장된 모든 데이터는 미사용 시 암호화됩니다", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "id": "D01.07", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "미사용 데이터 암호화", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "안전" + }, + { + "category": "데이터 보호", + "description": "Microsoft 서비스 간에 공용 인터넷을 통해 전송되는 데이터는 항상 TLS 1.2 이상으로 암호화됩니다. 패브릭은 가능할 때마다 TLS 1.3으로 협상합니다.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "id": "D01.08", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "전송 중인 데이터 암호화", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "안전" }, { "category": "ID 및 액세스 관리", @@ -172,6 +417,18 @@ "text": "필요한 경우 로컬 사용자 사용 제한", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "description": "아무 것도 할 필요가 없습니다. Fabric에 대한 모든 연결 요청은 Microsoft Entra ID로 인증되므로 사용자는 회사 사무실, 집에서 작업 할 때 또는 원격 위치에서 Fabric에 안전하게 연결할 수 있습니다.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "id": "E01.01", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "Microsoft Entra ID를 기본 인증 방법으로 사용", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "안전" + }, { "category": "ID 및 액세스 관리", "description": "관리 ID를 사용하면 자격 증명을 관리할 필요가 없습니다. 관리 ID는 Microsoft Entra 인증을 지원하는 리소스에 연결할 때 서비스 인스턴스에 대한 ID를 제공합니다.", @@ -184,6 +441,18 @@ "text": "관리 ID를 사용하여 서비스에 인증", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "description": "Fabric 워크스페이스 ID는 Fabric 워크스페이스와 연관될 수 있는 자동으로 관리되는 서비스 프린시펄입니다. 작업 영역 ID는 내 작업 영역을 제외한 모든 작업 영역의 작업 영역 설정에서 만들 수 있습니다. 작업 영역 ID에는 작업 영역 기여자 역할이 자동으로 할당되고 작업 영역 항목에 액세스할 수 있습니다. 제한 사항: 작업 영역 ID를 인증 방법으로 사용할 때 바로 가기 대상에 쓰기가 실패합니다. workspace-identity-authentication을 사용한 연결은 Onelake 바로 가기 및 데이터 파이프라인에서만 사용할 수 있습니다.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "id": "E01.02", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "작업 영역 ID를 사용하여 서비스에 인증", + "waf": "안전" + }, { "category": "ID 및 액세스 관리", "description": "일상적인 관리 작업에 필요하지 않은 경우 긴급 용도로만 로컬 관리자 계정을 사용하지 않도록 설정하거나 제한합니다.", @@ -195,6 +464,18 @@ "text": "높은 권한이 부여된/관리 사용자를 분리 및 제한하고 MFA 및 조건부 정책을 사용하도록 설정합니다.", "waf": "안전" }, + { + "category": "ID 및 액세스 관리", + "description": "스토리지 계정에 대한 ID 권한 부여Grant the identity permissions on the storage account", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "id": "E01.03", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "스토리지 계정에 대한 RBAC 역할을 관리 ID에 제공하여 성공적인 연결을 만듭니다.", + "waf": "안전" + }, { "category": "네트워크 보안", "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", @@ -202,7 +483,20 @@ "service": "Azure Data Factory", "severity": "보통", "subcategory": "", - "text": "공용 인터넷을 통한 액세스를 비활성화하고 방화벽 규칙 또는 신뢰할 수 있는 서비스 규칙을 구성합니다." + "text": "공용 인터넷을 통한 액세스를 비활성화하고 방화벽 규칙 또는 신뢰할 수 있는 서비스 규칙을 구성합니다.", + "waf": "안전" + }, + { + "category": "네트워킹", + "description": "작업 영역 ID가 있는 패브릭 작업 영역은 OneLake 바로 가기에 대한 신뢰할 수 있는 작업 영역 액세스를 통해 방화벽 지원 Azure Data Lake Storage Gen2 계정을 안전하게 읽거나 쓸 수 있습니다.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "id": "F01.01", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "방화벽 뒤의 스토리지 계정에 액세스하기 위해 신뢰할 수 있는 작업 영역 액세스 구성Configure trusted workspace access to access storage account behind firewall ", + "waf": "안전" }, { "category": "네트워크 보안", @@ -214,6 +508,19 @@ "text": "회사 네트워크를 벗어나지 않아야 하는 중요한 데이터로 작업하는 경우 VN에 SHIR VM을 배포합니다.", "waf": "안전" }, + { + "category": "네트워킹", + "description": "관리되는 가상 네트워크는 각 패브릭 작업 영역에 대해 Microsoft 패브릭에서 만들고 관리하는 가상 네트워크입니다. 관리형 가상 네트워크는 Fabric Spark 워크로드에 대한 네트워크 격리를 제공하며, 이는 컴퓨팅 클러스터가 전용 네트워크에 배포되고 더 이상 공유 가상 네트워크의 일부가 아님을 의미합니다. Fabric의 Spark 워크로드에 대해서만 지원됩니다.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "id": "F01.02", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "네트워크 격리가 필요한 경우 관리되는 vnet 옵션을 사용합니다.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "안전" + }, { "category": "네트워크 보안", "description": "Data Factory 관리 가상 네트워크 내에서 Azure 통합 런타임을 만들 때 통합 런타임은 관리되는 가상 네트워크로 프로비전됩니다. 프라이빗 엔드포인트를 사용하여 지원되는 데이터 저장소에 안전하게 연결합니다.", @@ -225,6 +532,19 @@ "text": "관리형 vnet IR을 사용하여 Azure Integration Runtime에 대한 공용 인터넷을 통한 액세스 제한", "waf": "안전" }, + { + "category": "네트워킹", + "description": "관리형 프라이빗 엔드포인트는 Fabric Spark 워크로드의 데이터 소스에 대한 보안 및 비공개 액세스를 허용하는 기능입니다. 스타터 풀은 관리형 PE와 함께 사용할 수 없습니다", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "id": "F01.03", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "Azure 서비스에 액세스하도록 관리형 프라이빗 엔드포인트 구성", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "안전" + }, { "category": "네트워크 보안", "description": "관리형 프라이빗 엔드포인트는 Azure 리소스에 대한 프라이빗 링크를 설정하는 Data Factory 관리형 가상 네트워크에서 만든 프라이빗 엔드포인트입니다. Data Factory는 사용자를 대신하여 이러한 프라이빗 엔드포인트를 관리합니다.", @@ -237,15 +557,94 @@ "text": "관리형 Azure IR을 사용하여 리소스에 연결하도록 관리형 프라이빗 엔드포인트 구성", "waf": "안전" }, + { + "category": "네트워킹", + "description": "Fabric은 가상 네트워크의 개인 IP 주소를 사용합니다. 엔드포인트를 사용하면 네트워크의 사용자가 개인 링크를 사용하여 개인 IP 주소를 통해 Fabric과 통신할 수 있습니다.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "id": "F01.04", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "자신의 Azure vnet의 리소스(예: Fabric 환경에서 들어오는 트래픽)에 액세스하도록 Private Links 구성", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "안전" + }, + { + "category": "네트워킹", + "description": "사용자 인증 시점은 IP 주소, 위치 및 관리 중인 디바이스를 포함할 수 있는 정책 집합에 따라 결정됩니다.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "id": "F01.05", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "사용자가 패브릭 환경에 액세스하려는 경우 Microsoft Entra ID 조건부 액세스를 구성합니다", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "안전" + }, + { + "category": "네트워킹", + "description": "Azure에서 서비스 태그는 네트워크 보안 규칙에 대한 업데이트 또는 변경의 복잡성을 최소화하기 위해 자동으로 그룹으로 관리되는 정의된 IP 주소 그룹입니다.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "id": "F01.06", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "Azure 서비스 태그를 사용하여 Microsoft 패브릭과의 연결을 사용하도록 설정할 수 있습니다.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "안전" + }, + { + "category": "네트워킹", + "description": "선택적", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "id": "F01.07", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "Fabric URL을 허용 목록에 추가할 수 있습니다", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "안전" + }, + { + "category": "네트워킹", + "description": "선택적", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "id": "F01.08", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "허용 목록에 Power BI URL을 추가할 수 있습니다", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "안전" + }, + { + "category": "네트워킹", + "description": "데이터 게이트웨이를 사용하면 Azure 및 기타 데이터 서비스를 Microsoft Fabric 및 Power Platform에 연결하여 데이터 원본과 안전하게 통신하고, 쿼리를 실행하고, 결과를 서비스로 다시 전송할 수 있습니다.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "id": "F01.09", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "보통", + "subcategory": "", + "text": "온-프레미스 데이터 게이트웨이 또는 Vnet 데이터 게이트웨이를 구성하고 사용하여 온-프레미스 또는 가상 네트워크 뒤의 소스에 연결합니다.", + "waf": "안전" + }, { "category": "", "description": "Azure Private Link를 사용하면 프라이빗 엔드포인트를 통해 Azure의 다양한 PaaS(Platform as a Service) 배포에 연결할 수 있습니다. 프라이빗 엔드포인트는 특정 가상 네트워크 및 서브넷 내의 개인 IP 주소입니다", "guid": "b47a393a-0804-4272-a479-8b1578b219a4", "id": "G01.01", "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", "severity": "보통", "subcategory": "", - "text": "고객 Vnet 및 데이터 팩터리의 원본에 연결하도록 Private Links 구성" + "text": "고객 Vnet 및 데이터 팩터리의 원본에 연결하도록 Private Links 구성", + "waf": "안전" }, { "category": "데이터 보호", @@ -301,7 +700,8 @@ "service": "Azure Data Factory", "severity": "보통", "subcategory": "", - "text": "파이프라인 활동에서 Azure Key Vault 비밀 사용Use Azure Key Vault secrets in pipeline activities" + "text": "파이프라인 활동에서 Azure Key Vault 비밀 사용Use Azure Key Vault secrets in pipeline activities", + "waf": "안전" }, { "category": "데이터 보호", @@ -312,7 +712,8 @@ "service": "Azure Data Factory", "severity": "보통", "subcategory": "", - "text": "Azure Data Factory에서 SHIR 데이터 저장소를 사용하여 온-프레미스에 대한 자격 증명 암호화" + "text": "Azure Data Factory에서 SHIR 데이터 저장소를 사용하여 온-프레미스에 대한 자격 증명 암호화", + "waf": "안전" }, { "category": "ID 및 액세스 관리", @@ -636,9 +1037,11 @@ "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", "id": "P01.01", "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", "severity": "높다", "subcategory": "", - "text": "작업 영역 관리자 제한" + "text": "작업 영역 관리자 제한", + "waf": "안전" }, { "category": "ID 및 액세스 관리", @@ -657,7 +1060,8 @@ "id": "R01.01", "severity": "높다", "subcategory": "", - "text": "키를 주기적으로 사용하는 경우 키를 재생/회전합니다." + "text": "키를 주기적으로 사용하는 경우 키를 재생/회전합니다.", + "waf": "안전" }, { "category": "ID 및 액세스 관리", @@ -745,7 +1149,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": "Preview", - "timestamp": "October 21, 2024", + "timestamp": "October 23, 2024", "waf": "Security" }, "severities": [ diff --git a/checklists/datasecurity_checklist.pt.json b/checklists/datasecurity_checklist.pt.json index 2cf308c6..dfb7187f 100644 --- a/checklists/datasecurity_checklist.pt.json +++ b/checklists/datasecurity_checklist.pt.json @@ -12,6 +12,18 @@ "text": "Restringir o uso de usuários locais em cargas de trabalho sql no Synapse", "waf": "Segurança" }, + { + "category": "Proteção de dados", + "description": "Nenhuma configuração adicional é necessária, pois isso é habilitado em uma implantação padrão.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Criptografar dados confidenciais em trânsito", + "waf": "Segurança" + }, { "category": "Gerenciamento de identidade e acesso", "description": "Use a ID do Microsoft Entra como o método de autenticação padrão para controlar o acesso ao plano de dados.", @@ -24,6 +36,16 @@ "text": "Usar identidade gerenciada para autenticar nos serviços", "waf": "Segurança" }, + { + "category": "Proteção de dados", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "id": "A01.02", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Habilitar a criptografia de dados em repouso por padrão", + "waf": "Segurança" + }, { "category": "Gerenciamento de identidade e acesso", "description": "Se não for necessário para operações administrativas de rotina, desabilite ou restrinja todas as contas de administrador local apenas para uso emergencial.", @@ -35,6 +57,18 @@ "text": "Separe e limite usuários altamente privilegiados/administrativos e habilite políticas condicionais e de MFA", "waf": "Segurança" }, + { + "category": "Proteção de dados", + "description": "Usar o Keyvaults para armazenar sua CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Usar a opção de chave gerenciada pelo cliente na criptografia de dados em repouso quando necessário", + "waf": "Segurança" + }, { "category": "Gerenciamento de identidade e acesso", "description": "O Azure Synapse também inclui funções RBAC (controle de acesso baseado em função) do Synapse para gerenciar diferentes aspectos do Synapse Studio. Aproveite essas funções internas para atribuir permissões a usuários, grupos ou outras entidades de segurança para gerenciar quem pode Publicar artefatos de código e listar ou acessar artefatos de código publicados,Executar código em pools do Apache Spark e runtimes de integração,Acessar serviços vinculados (dados) protegidos por credenciais,Monitorar ou cancelar execuções de trabalho, revisar a saída do trabalho e os logs de execução.", @@ -70,6 +104,17 @@ "text": "Usar o espaço de trabalho vnet gerenciado para restringir o acesso pela Internet pública", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Use a ID do Microsoft Entra como o método de autenticação padrão.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "id": "B01.01", + "service": "Azure Event Hubs", + "severity": "Alto", + "subcategory": "", + "text": "Use o Microsoft Entra ID como o método de autenticação padrão e desabilite o acesso local sempre que possível", + "waf": "Segurança" + }, { "category": "Segurança de rede", "description": "Para proteger dados confidenciais, é recomendável desabilitar totalmente o acesso público aos pontos de extremidade do workspace. Ao fazer isso, ele garante que todos os pontos de extremidade do workspace só possam ser acessados usando pontos de extremidade privados.", @@ -82,6 +127,17 @@ "text": "Configure pontos de extremidade privados para se conectar aos serviços externos e desabilitar o acesso público", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Use a ID do Microsoft Entra como o método de autenticação padrão.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "id": "B01.02", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Usar identidade gerenciada para autenticar nos serviços", + "waf": "Segurança" + }, { "category": "Segurança de rede", "description": "Se o acesso público precisar ser habilitado, é altamente recomendável configurar as regras de firewall IP para permitir conexões de entrada somente da lista especificada de endereços IP públicos.", @@ -93,6 +149,16 @@ "text": "Se habilitar o acesso público, é altamente recomendável configurar regras de firewall IP", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "id": "B01.03", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Configurar políticas de acesso condicional para restringir o acesso no plano de dados", + "waf": "Segurança" + }, { "category": "Segurança de rede", "guid": "d234292b-7528-4537-a551-c5bf4e4f1854", @@ -104,6 +170,17 @@ "text": "Implante VMs SHIR em sua rede virtual se você estiver trabalhando com dados confidenciais que não devem sair da rede corporativa", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Restringir a exposição de chaves e secerts", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "B01.04", + "service": "Azure Event Hubs", + "severity": "Alto", + "subcategory": "", + "text": "Use o Azure Key Vaults para armazenar segredos e créditos.", + "waf": "Segurança" + }, { "category": "Segurança de rede", "description": "Isso só pode ser feito ao implantar o workspace, mas não há suporte para bibliotecas Python instaladas de repositórios públicos como o PyPI. (Pense na limitação antes de habilitá-la)", @@ -116,6 +193,40 @@ "text": "Habilitar DEP (Proteção contra Exfiltração de Dados)", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "id": "B01.05", + "service": "Azure Event Hubs", + "severity": "Alto", + "subcategory": "", + "text": "Separar e limitar usuários altamente privilegiados/administrativos", + "waf": "Segurança" + }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Quando você cria um namespace dos Hubs de Eventos, uma regra de política chamada RootManageSharedAccessKey é criada automaticamente para o namespace. Essa política tem permissões de gerenciamento para todo o namespace. É recomendável que você trate essa regra como uma conta raiz administrativa e não a use em seu aplicativo. Você pode criar regras de política adicionais na guia Configurar para o namespace no portal, por meio do PowerShell ou da CLI do Azure. Evite o uso de métodos ou contas de autenticação locais, eles devem ser desativados sempre que possível. Em vez disso, use o Azure AD para autenticar sempre que possível.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Autenticar o acesso aos recursos dos Hubs de Eventos usando SAS (assinaturas de acesso compartilhado) e restringir usuários locais", + "waf": "Segurança" + }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Use o RBAC (controle de acesso baseado em função) do Azure para gerenciar o acesso a recursos do Azure por meio de atribuições de função internas. As funções RBAC do Azure podem ser atribuídas a usuários, grupos, entidades de serviço e identidades gerenciadas.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "id": "B01.07", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Usar RBACs do Azure para granular o acesso ", + "waf": "Segurança" + }, { "category": "Proteção de dados", "description": "A primeira camada de criptografia é feita por chaves gerenciadas pela Microsoft, você pode adicionar uma segunda camada de criptografia usando chaves gerenciadas pelo cliente", @@ -128,6 +239,17 @@ "text": "Criptografia de dados em repouso usando chaves gerenciadas pelo cliente para workspace", "waf": "Segurança" }, + { + "category": "Rede", + "description": "O serviço dá suporte à desabilitação do acesso à rede pública usando a regra de filtragem de ACL IP no nível do serviço (não NSG ou Firewall do Azure) ou usando uma opção de alternância 'Desabilitar Acesso à Rede Pública'.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "id": "C01.01", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Desativar acesso à rede pública", + "waf": "Segurança" + }, { "category": "Proteção de dados", "description": "O Azure Synapse aproveita o TLS para garantir que os dados sejam criptografados em movimento. Os pools dedicados do SQL dão suporte às versões TLS 1.0, TLS 1.1 e TLS 1.2 para criptografia em que os drivers fornecidos pela Microsoft usam o TLS 1.2 por padrão. O pool de SQL sem servidor e o pool do Apache Spark usam o TLS 1.2 para todas as conexões de saída.", @@ -140,6 +262,16 @@ "text": "Criptografia de dados em trânsito ", "waf": "Segurança" }, + { + "category": "Rede", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "id": "C01.02", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Usar Vnets para isolar o tráfego na rede restrita ", + "waf": "Segurança" + }, { "category": "Proteção de dados", "description": "Usar Keyvaults para armazenar seus segredos e credenciais", @@ -151,15 +283,128 @@ "text": "Armazenar senhas, certificados e chaves no cofre de chaves do Azure", "waf": "Segurança" }, + { + "category": "Rede", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "Média", + "subcategory": "", + "text": "Implante pontos de extremidade privados para todos os recursos do Azure que dão suporte ao recurso Link Privado para estabelecer um ponto de acesso privado para os recursos.", + "waf": "Segurança" + }, { "category": "", "description": "Você pode armazenar credenciais ou valores secretos em um Azure Key Vault e usá-los durante a execução do pipeline para passar para suas atividades.", "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", "id": "D01.01", "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "Média", + "subcategory": "", + "text": "Usar segredos do Azure Key Vault em atividades de pipeline", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "A malha controla o acesso a dados usando espaços de trabalho. Nos espaços de trabalho, os dados aparecem na forma de itens de malha e os usuários não podem visualizar ou usar itens (dados), a menos que você conceda a eles acesso ao espaço de trabalho. Você pode encontrar mais informações sobre permissões de espaço de trabalho e item em Modelo de permissão.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "id": "D01.01", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Use funções de espaço de trabalho para fornecer acesso aos usuários nos dados", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "O OneLake RBAC usa atribuições de função para aplicar permissões a seus membros.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "id": "D01.02", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Use o RBAC no Onelake para fornecer acesso refinado aos dados em Tabelas/Arquivos Onelake ", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "Leve em conta o acesso do usuário no local de destino e de origem do atalho", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "id": "D01.03", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Ao usar atalhos, a identidade do usuário também deve ter acesso ao local de destino do atalho", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "Nem todos os usuários precisam ter acesso a todo o espaço de trabalho usando funções, portanto, restrinja a atribuição de funções em todo o espaço de trabalho e compartilhe o item apenas com o usuário usando o recurso de compartilhamento de item ou permissão de gerenciamento no Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "id": "D01.04", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Restringir o fornecimento de função no nível do espaço de trabalho aos usuários, em vez de compartilhar um item apenas com os usuários", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "Use recursos como RLS, CLS e mascaramento de dados dinâmicos para aprimorar seus requisitos de segurança de dados em cargas de trabalho SQL.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "id": "D01.05", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", "severity": "Média", "subcategory": "", - "text": "Usar segredos do Azure Key Vault em atividades de pipeline" + "text": "Limite o acesso aos dados definindo RLS, CLS e mascaramento de dados dinâmicos em pontos de extremidade de análise de SQL e Warehouse", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "Use recursos como RLS e OLS no Power BI para ter mais recursos de segurança em modelos semânticos", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "id": "D01.06", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Limitar o acesso aos dados definindo RLS e OLS em modelos semânticos no Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "No Fabric, todos os dados armazenados no OneLake são criptografados em repouso", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "id": "D01.07", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Criptografar dados em repouso", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Segurança" + }, + { + "category": "Proteção de dados", + "description": "Os dados em trânsito pela Internet pública entre os serviços da Microsoft são sempre criptografados com pelo menos TLS 1.2. A malha negocia com o TLS 1.3 sempre que possível.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "id": "D01.08", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Criptografar dados em trânsito", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" }, { "category": "Gerenciamento de identidade e acesso", @@ -172,6 +417,18 @@ "text": "Restrinja o uso de usuários locais sempre que necessário", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Não há necessidade de fazer nada. Cada solicitação para se conectar ao Fabric é autenticada com a ID do Microsoft Entra, permitindo que os usuários se conectem com segurança ao Fabric de seu escritório corporativo, ao trabalhar em casa ou de um local remoto.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "id": "E01.01", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Usar o Microsoft Entra ID como método de autenticação padrão", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" + }, { "category": "Gerenciamento de identidade e acesso", "description": "As identidades gerenciadas eliminam a necessidade de gerenciar credenciais. As identidades gerenciadas fornecem uma identidade para a instância de serviço ao se conectar a recursos que dão suporte à autenticação do Microsoft Entra.", @@ -184,6 +441,18 @@ "text": "Usar identidade gerenciada para autenticar nos serviços", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Uma identidade de workspace do Fabric é uma entidade de serviço gerenciada automaticamente que pode ser associada a um workspace do Fabric. As identidades do workspace podem ser criadas nas configurações do workspace de qualquer workspace, exceto Meus workspaces. Uma identidade de workspace recebe automaticamente a função de colaborador do workspace e tem acesso aos itens do workspace. Limitação: Falha na gravação no destino do atalho ao usar a identidade do workspace como método de autenticação. As conexões com workspace-identity-authentication só podem ser usadas em atalhos Onelake e pipelines de dados.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "id": "E01.02", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Usar a identidade do workspace para autenticar nos serviços", + "waf": "Segurança" + }, { "category": "Gerenciamento de identidade e acesso", "description": "Se não for necessário para operações administrativas de rotina, desabilite ou restrinja todas as contas de administrador local apenas para uso emergencial.", @@ -195,6 +464,18 @@ "text": "Separe e limite usuários altamente privilegiados/administrativos e habilite políticas condicionais e de MFA", "waf": "Segurança" }, + { + "category": "Gerenciamento de identidade e acesso", + "description": "Conceder as permissões de identidade na conta de armazenamento", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "id": "E01.03", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Fornecer funções RBAC na conta de armazenamento para a identidade gerenciada para fazer uma conexão bem-sucedida", + "waf": "Segurança" + }, { "category": "Segurança de rede", "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", @@ -202,7 +483,20 @@ "service": "Azure Data Factory", "severity": "Média", "subcategory": "", - "text": "Desabilitar o acesso pela Internet pública e configurar regras de firewall ou regras de serviços confiáveis" + "text": "Desabilitar o acesso pela Internet pública e configurar regras de firewall ou regras de serviços confiáveis", + "waf": "Segurança" + }, + { + "category": "Rede", + "description": "Os workspaces do Fabric com uma identidade de workspace podem ler ou gravar com segurança em contas do Azure Data Lake Storage Gen2 habilitadas para firewall por meio do acesso confiável ao workspace para atalhos do OneLake.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "id": "F01.01", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Configurar o acesso ao workspace confiável para acessar a conta de armazenamento atrás do firewall ", + "waf": "Segurança" }, { "category": "Segurança de rede", @@ -214,6 +508,19 @@ "text": "Implante VMs SHIR em sua rede virtual se você estiver trabalhando com dados confidenciais que não devem sair da rede corporativa", "waf": "Segurança" }, + { + "category": "Rede", + "description": "As redes virtuais gerenciadas são redes virtuais criadas e gerenciadas pelo Microsoft Fabric para cada workspace do Fabric. As redes virtuais gerenciadas fornecem isolamento de rede para cargas de trabalho do Fabric Spark, o que significa que os clusters de computação são implantados em uma rede dedicada e não fazem mais parte da rede virtual compartilhada. Ele só tem suporte para carga de trabalho do Spark no Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "id": "F01.02", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Use a opção vnet gerenciada se você tiver necessidades de isolamento de rede", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Segurança" + }, { "category": "Segurança de rede", "description": "Quando você cria um runtime de integração do Azure em uma rede virtual gerenciada do Data Factory, o runtime de integração é provisionado com a rede virtual gerenciada. Ele usa pontos de extremidade privados para se conectar com segurança a armazenamentos de dados com suporte.", @@ -225,6 +532,19 @@ "text": "Usar o IR de vnet gerenciado para restringir o acesso pela Internet pública para o Azure Integration Runtime", "waf": "Segurança" }, + { + "category": "Rede", + "description": "Os pontos de extremidade privados gerenciados são recursos que permitem acesso seguro e privado a fontes de dados de cargas de trabalho do Fabric Spark. Você não pode usar o pool inicial com PE gerenciado", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "id": "F01.03", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Configurar pontos de extremidade privados gerenciados para acessar os serviços do Azure", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" + }, { "category": "Segurança de rede", "description": "Os pontos de extremidade privados gerenciados são pontos de extremidade privados criados na rede virtual gerenciada do Data Factory que estabelece um link privado para os recursos do Azure. O Data Factory gerencia esses pontos de extremidade privados em seu nome.", @@ -237,15 +557,94 @@ "text": "Configurar pontos de extremidade privados gerenciados para se conectar a recursos usando o Azure IR gerenciado", "waf": "Segurança" }, + { + "category": "Rede", + "description": "O Fabric usa um endereço IP privado da sua rede virtual. O endpoint permite que os usuários em sua rede se comuniquem com o Fabric pelo endereço IP privado usando links privados.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "id": "F01.04", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Configure Links Privados para acessar recursos em sua própria rede virtual do Azure, ou seja, o tráfego que vem em seu ambiente do Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" + }, + { + "category": "Rede", + "description": "Quando um usuário autentica, o acesso é determinado com base em um conjunto de políticas que podem incluir endereço IP, localização e dispositivos gerenciados.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "id": "F01.05", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Configurar o acesso condicional do Microsoft Entra ID se um usuário estiver tentando acessar seu ambiente do Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" + }, + { + "category": "Rede", + "description": "No Azure, uma marca de serviço é um grupo definido de endereços IP que é gerenciado automaticamente, como um grupo, para minimizar a complexidade das atualizações ou alterações nas regras de segurança de rede.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "id": "F01.06", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Você pode usar marcas de serviço do Azure para habilitar conexões de e para o Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Segurança" + }, + { + "category": "Rede", + "description": "opcional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "id": "F01.07", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Você pode adicionar URLs de estrutura à sua lista de permissões", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Segurança" + }, + { + "category": "Rede", + "description": "opcional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "id": "F01.08", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Você pode adicionar URLs do Power BI à sua lista de permissões", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Segurança" + }, + { + "category": "Rede", + "description": "O gateway de dados permite que você conecte seu Azure e outros serviços de dados ao Microsoft Fabric e ao Power Platform para se comunicar com segurança com a fonte de dados, executar consultas e transmitir resultados de volta ao serviço.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "id": "F01.09", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "Média", + "subcategory": "", + "text": "Configurar e usar o gateway de dados local ou o gateway de dados Vnet para se conectar a fontes locais ou atrás de uma rede virtual", + "waf": "Segurança" + }, { "category": "", "description": "Usando o Link Privado do Azure, você pode se conectar a várias implantações de PaaS (plataforma como serviço) no Azure por meio de um ponto de extremidade privado. Um ponto de extremidade privado é um endereço IP privado em uma rede virtual e sub-rede específicas", "guid": "b47a393a-0804-4272-a479-8b1578b219a4", "id": "G01.01", "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", "severity": "Média", "subcategory": "", - "text": "Configurar Links Privados para se conectar a fontes na Vnet do cliente e no data factory" + "text": "Configurar Links Privados para se conectar a fontes na Vnet do cliente e no data factory", + "waf": "Segurança" }, { "category": "Proteção de dados", @@ -301,7 +700,8 @@ "service": "Azure Data Factory", "severity": "Média", "subcategory": "", - "text": "Usar segredos do Azure Key Vault em atividades de pipeline" + "text": "Usar segredos do Azure Key Vault em atividades de pipeline", + "waf": "Segurança" }, { "category": "Proteção de dados", @@ -312,7 +712,8 @@ "service": "Azure Data Factory", "severity": "Média", "subcategory": "", - "text": "Criptografar credenciais para locais usando armazenamentos de dados SHIR no Azure Data Factory" + "text": "Criptografar credenciais para locais usando armazenamentos de dados SHIR no Azure Data Factory", + "waf": "Segurança" }, { "category": "Gerenciamento de identidade e acesso", @@ -636,9 +1037,11 @@ "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", "id": "P01.01", "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", "severity": "Alto", "subcategory": "", - "text": "Restringir administradores do workspace" + "text": "Restringir administradores do workspace", + "waf": "Segurança" }, { "category": "Gerenciamento de identidade e acesso", @@ -657,7 +1060,8 @@ "id": "R01.01", "severity": "Alto", "subcategory": "", - "text": "Regenerar/girar chaves se usá-las periodicamente" + "text": "Regenerar/girar chaves se usá-las periodicamente", + "waf": "Segurança" }, { "category": "Gerenciamento de identidade e acesso", @@ -745,7 +1149,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": "Preview", - "timestamp": "October 21, 2024", + "timestamp": "October 23, 2024", "waf": "Security" }, "severities": [ diff --git a/checklists/datasecurity_checklist.zh-Hant.json b/checklists/datasecurity_checklist.zh-Hant.json index d4e33ea0..67846707 100644 --- a/checklists/datasecurity_checklist.zh-Hant.json +++ b/checklists/datasecurity_checklist.zh-Hant.json @@ -12,6 +12,18 @@ "text": "限制本地使用者對 Synapse 上的 sql 工作負載使用", "waf": "安全" }, + { + "category": "數據保護", + "description": "不需要其他配置,因為此功能已在預設部署中啟用。", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "id": "A01.01", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "加密傳輸中的敏感數據", + "waf": "安全" + }, { "category": "身份和訪問管理", "description": "使用 Microsoft Entra ID 作為預設身份驗證方法來控制數據平面訪問。", @@ -24,6 +36,16 @@ "text": "使用託管標識對服務進行身份驗證", "waf": "安全" }, + { + "category": "數據保護", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "id": "A01.02", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "默認啟用靜態數據加密", + "waf": "安全" + }, { "category": "身份和訪問管理", "description": "如果日常管理操作不需要,請禁用或限制任何本地管理員帳戶,以供緊急使用。", @@ -35,6 +57,18 @@ "text": "分離和限制高許可權/管理使用者,並啟用 MFA 和條件策略", "waf": "安全" }, + { + "category": "數據保護", + "description": "使用 Keyvaults 儲存 CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "id": "A01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "需要時,在靜態數據加密中使用客戶管理的金鑰選項", + "waf": "安全" + }, { "category": "身份和訪問管理", "description": "Azure Synapse 還包括 Synapse 基於角色的訪問控制 (RBAC) 角色,用於管理 Synapse Studio 的不同方面。利用這些內置角色為使用者、組或其他安全主體分配許可權,以管理誰可以發佈代碼構件並列出或訪問已發佈的代碼構件、在 Apache Spark 池和集成運行時上執行代碼、訪問受憑據保護的連結(數據)服務、監控或取消作業執行、查看作業輸出和執行日誌。", @@ -70,6 +104,17 @@ "text": "使用託管 vnet 工作區限制通過公共 Internet 的訪問", "waf": "安全" }, + { + "category": "身份和訪問管理", + "description": "使用 Microsoft Entra ID 作為預設身份驗證方法。", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "id": "B01.01", + "service": "Azure Event Hubs", + "severity": "高", + "subcategory": "", + "text": "使用 Microsoft Entra ID 作為預設身份驗證方法,並盡可能禁用本地訪問", + "waf": "安全" + }, { "category": "網路安全", "description": "為了保護任何敏感數據,建議完全禁用對 Workspace 終端節點的公共訪問。通過這樣做,它可以確保所有工作區端點只能使用私有端點訪問。", @@ -82,6 +127,17 @@ "text": "配置專用終結點以連接到外部服務並禁用公有訪問", "waf": "安全" }, + { + "category": "身份和訪問管理", + "description": "使用 Microsoft Entra ID 作為預設身份驗證方法。", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "id": "B01.02", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "使用託管標識對服務進行身份驗證", + "waf": "安全" + }, { "category": "網路安全", "description": "如果需要啟用公有訪問,強烈建議將IP防火牆規則配置為僅允許來自指定公有IP位址清單的入站連接。", @@ -93,6 +149,16 @@ "text": "如果啟用公網訪問,強烈建議配置 IP 防火牆規則", "waf": "安全" }, + { + "category": "身份和訪問管理", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "id": "B01.03", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "配置條件訪問策略以限制對數據平面的訪問", + "waf": "安全" + }, { "category": "網路安全", "guid": "d234292b-7528-4537-a551-c5bf4e4f1854", @@ -104,6 +170,17 @@ "text": "如果正在處理不應離開公司網路的敏感數據,請在 vnet 中部署 SHIR VM", "waf": "安全" }, + { + "category": "身份和訪問管理", + "description": "限制金鑰和 secert 的公開", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "id": "B01.04", + "service": "Azure Event Hubs", + "severity": "高", + "subcategory": "", + "text": "使用 Azure Key Vault 儲存機密和密碼。", + "waf": "安全" + }, { "category": "網路安全", "description": "這隻能在部署工作區時完成,但不支援從 PyPI 等公共存儲庫安裝的 Python 庫。( 在啟用之前考慮限制 )", @@ -116,6 +193,40 @@ "text": "開啟資料洩露保護 (DEP)", "waf": "安全" }, + { + "category": "身份和訪問管理", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "id": "B01.05", + "service": "Azure Event Hubs", + "severity": "高", + "subcategory": "", + "text": "分離和限制高許可權/管理使用者", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "description": "創建事件中心命名空間時,會自動為該命名空間創建名為 RootManageSharedAccessKey 的策略規則。此策略具有整個命名空間的manage許可權。建議您將此規則視為管理 root 帳戶,不要在應用程式中使用它。您可以通過 PowerShell 或 Azure CLI 在門戶中為命名空間的 Configure (配置) 選項卡中創建其他策略規則。避免使用本地身份驗證方法或帳戶,應盡可能禁用這些方法或帳戶。請盡可能使用 Azure AD 進行身份驗證。", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "id": "B01.06", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "使用共用訪問簽名 (SAS) 驗證對事件中心資源的訪問並限制本地使用者", + "waf": "安全" + }, + { + "category": "身份和訪問管理", + "description": "使用 Azure 基於角色的訪問控制 (Azure RBAC) 通過內置角色分配來管理 Azure 資源訪問。可以將 Azure RBAC 角色分配給使用者、組、服務主體和託管標識。", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "id": "B01.07", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "使用 Azure RBAC 精細化訪問", + "waf": "安全" + }, { "category": "數據保護", "description": "第一層加密由 Microsoft 託管金鑰完成,您可以使用客戶託管金鑰添加第二層加密", @@ -128,6 +239,17 @@ "text": "使用客戶管理的 Workspace 金鑰進行靜態數據加密", "waf": "安全" }, + { + "category": "聯網", + "description": "服務支援通過使用服務級別 IP ACL 篩選規則(而不是 NSG 或 Azure 防火牆)或使用“禁用公用網络訪問”切換開關來禁用公用網络訪問。", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "id": "C01.01", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "禁用公共網路訪問", + "waf": "安全" + }, { "category": "數據保護", "description": "Azure Synapse 利用 TLS 來確保數據在動態中加密。SQL 專用池支援 TLS 1.0、TLS 1.1 和 TLS 1.2 版本進行加密,其中 Microsoft 提供的驅動程式預設使用 TLS 1.2。無伺服器 SQL 池和 Apache Spark 池對所有出站連接使用 TLS 1.2。", @@ -140,6 +262,16 @@ "text": "傳輸中的數據加密", "waf": "安全" }, + { + "category": "聯網", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "id": "C01.02", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "使用 Vnet 隔離受限網路上的流量", + "waf": "安全" + }, { "category": "數據保護", "description": "使用 Keyvaults 儲存機密和憑據", @@ -151,15 +283,128 @@ "text": "將密碼、secert 和密鑰存儲在 Azure Key Vault 中", "waf": "安全" }, + { + "category": "聯網", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "id": "C01.03", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "中等", + "subcategory": "", + "text": "為支援專用連結功能的所有 Azure 資源部署專用終結點,以便為資源建立專用訪問點。", + "waf": "安全" + }, { "category": "", "description": "您可以將憑據或機密值存儲在 Azure Key Vault 中,並在管道執行期間使用它們以傳遞給您的活動。", "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", "id": "D01.01", "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "中等", + "subcategory": "", + "text": "在管道活動中使用 Azure Key Vault 機密", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "Fabric 使用工作區控制數據訪問。在工作區中,數據以 Fabric 項的形式顯示,除非您授予使用者對工作區的訪問許可權,否則使用者無法查看或使用項(數據)。您可以在許可權模型 中找到有關工作區和項目許可權的更多資訊。", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "id": "D01.01", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "使用 Workspace 角色向使用者提供對數據的訪問許可權", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "OneLake RBAC 使用角色分配將許可權應用於其成員。", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "id": "D01.02", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "在 Onelake 上使用 RBAC 提供對 Tables/Files Onelake 中數據的精細訪問", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "考慮使用者在快捷方式的目標和源位置的訪問許可權", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "id": "D01.03", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "使用快捷方式時,用戶的使用者身份也應具有對快捷方式目標位置的訪問許可權", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "並非所有使用者都需要使用角色訪問整個工作區,因此請限制授予整個工作區的角色,並且僅使用共用項功能或 Fabric 中的管理許可權將項共用給使用者", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "id": "D01.04", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "限制向使用者提供工作區級別角色,而是僅向使用者共享專案", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "使用 RLS、CLS 和動態數據遮罩等功能來增強您對 SQL 工作負載的數據安全要求。", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "id": "D01.05", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", "severity": "中等", "subcategory": "", - "text": "在管道活動中使用 Azure Key Vault 機密" + "text": "通過在 Warehouse 和 SQL 分析終端節點上定義 RLS、CLS 和動態數據掩碼來限制對數據的訪問", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "使用 Power BI 上的 RLS 和 OLS 等功能,在語義模型上獲得更多安全功能", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "id": "D01.06", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "通過在Power BI中的語義模型上定義 RLS 和 OLS 來限制對數據的訪問", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "在 Fabric 中,存儲在 OneLake 中的所有數據都是靜態加密的", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "id": "D01.07", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "加密靜態數據", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "安全" + }, + { + "category": "數據保護", + "description": "在 Microsoft 服務之間通過公共 Internet 傳輸的數據始終至少使用 TLS 1.2 進行加密。Fabric 會盡可能協商到 TLS 1.3。", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "id": "D01.08", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "加密傳輸中的數據", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" }, { "category": "身份和訪問管理", @@ -172,6 +417,18 @@ "text": "在必要時限制使用本地使用者", "waf": "安全" }, + { + "category": "身份和訪問管理", + "description": "無需執行任何操作。連接到 Fabric 的每個請求都使用 Microsoft Entra ID 進行身份驗證,允許使用者從公司辦公室、在家工作或遠端位置安全地連接到 Fabric。", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "id": "E01.01", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "使用 Microsoft Entra ID 作為預設身份驗證方法", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, { "category": "身份和訪問管理", "description": "託管身份消除了管理憑證的需要。託管標識在連接到支援 Microsoft Entra 身份驗證的資源時為服務實例提供標識。", @@ -184,6 +441,18 @@ "text": "使用託管標識對服務進行身份驗證", "waf": "安全" }, + { + "category": "身份和訪問管理", + "description": "Fabric 工作區標識是可與 Fabric 工作區關聯的自動託管服務主體。可以在除 My workspaces(我的工作區)之外的任何工作區的工作區設置中創建工作區身份。系統會自動為工作區標識分配工作區參與者角色,並有權訪問工作區專案。 限制:使用 Workspace Identity 作為身份驗證方法時,寫入快捷方式目標失敗。帶有 workspace-identity-authentication 的連接只能在 Onelake 快捷方式和數據管道中使用。", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "id": "E01.02", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "使用 workspace identity 對服務進行身份驗證", + "waf": "安全" + }, { "category": "身份和訪問管理", "description": "如果日常管理操作不需要,請禁用或限制任何本地管理員帳戶,以供緊急使用。", @@ -195,6 +464,18 @@ "text": "分離和限制高許可權/管理使用者,並啟用 MFA 和條件策略", "waf": "安全" }, + { + "category": "身份和訪問管理", + "description": "授予對存儲帳戶的標識許可權", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "id": "E01.03", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "將存儲帳戶上的 RBAC 角色提供給託管標識以建立成功連接", + "waf": "安全" + }, { "category": "網路安全", "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", @@ -202,7 +483,20 @@ "service": "Azure Data Factory", "severity": "中等", "subcategory": "", - "text": "禁用通過公共 Internet 的訪問,並配置防火牆規則或受信任的服務規則" + "text": "禁用通過公共 Internet 的訪問,並配置防火牆規則或受信任的服務規則", + "waf": "安全" + }, + { + "category": "聯網", + "description": "具有工作區標識的結構工作區可以通過 OneLake 快捷方式的受信任工作區訪問許可權安全地讀取或寫入啟用了防火牆的 Azure Data Lake Storage Gen2 帳戶。", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "id": "F01.01", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "配置受信任的工作區訪問許可權以訪問防火牆後面的存儲帳戶", + "waf": "安全" }, { "category": "網路安全", @@ -214,6 +508,19 @@ "text": "如果正在處理不應離開公司網路的敏感數據,請在 vnet 中部署 SHIR VM", "waf": "安全" }, + { + "category": "聯網", + "description": "託管虛擬網路是由 Microsoft Fabric 為每個 Fabric 工作區創建和管理的虛擬網路。託管虛擬網路為 Fabric Spark 工作負載提供網路隔離,這意味著計算集群部署在專用網路中,不再是共用虛擬網路的一部分。它僅支援 Fabric 中的 Spark 工作負載。", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "id": "F01.02", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "如果您有網路隔離需求,請使用託管 vnet 選項", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "安全" + }, { "category": "網路安全", "description": "在數據工廠託管的虛擬網路中創建 Azure 集成運行時時,集成運行時將預配託管的虛擬網路。它使用私有終端節點安全地連接到支援的數據存儲。", @@ -225,6 +532,19 @@ "text": "使用託管 vnet IR 限制 Azure Integration Runtime 通過公共 Internet 的訪問", "waf": "安全" }, + { + "category": "聯網", + "description": "託管專用終端節點是一項功能,允許從 Fabric Spark 工作負載對數據源進行安全和私有訪問。您不能將 Starter Pool 與託管 PE 一起使用", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "id": "F01.03", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "配置託管專用終結點以訪問 Azure 服務", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, { "category": "網路安全", "description": "託管專用終結點是在數據工廠託管虛擬網路中創建的專用終結點,用於建立指向 Azure 資源的專用連結。數據工廠代表你管理這些專用終結點。", @@ -237,15 +557,94 @@ "text": "配置託管專用終結點以使用託管 Azure IR 連接到資源", "waf": "安全" }, + { + "category": "聯網", + "description": "Fabric 使用虛擬網路中的專用IP位址。終端節點允許您網路中的使用者使用私有連結通過私有IP位址與 Fabric 通信。", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "id": "F01.04", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "配置專用連結以訪問你自己的 Azure vnet 中的資源,即傳入 Fabric 環境的流量", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "category": "聯網", + "description": "當使用者進行身份驗證時,訪問是根據一組策略確定的,這些策略可能包括IP位址、位置和託管設備。", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "id": "F01.05", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "如果使用者嘗試訪問您的 Fabric 環境,請配置 Microsoft Entra ID 條件訪問", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "category": "聯網", + "description": "在 Azure 中,服務標記是一組定義的 IP 位址,它作為一個組自動進行管理,以最大程度地降低網路安全規則更新或更改的複雜性。", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "id": "F01.06", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "您可以使用 Azure 服務標記來啟用與 Microsoft Fabric 之間的連接。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "安全" + }, + { + "category": "聯網", + "description": "自選", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "id": "F01.07", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "您可以將 Fabric URL 加入到您的白名單中", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "安全" + }, + { + "category": "聯網", + "description": "自選", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "id": "F01.08", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "您可以將 Power BI URL 新增到允許清單", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "安全" + }, + { + "category": "聯網", + "description": "數據閘道允許您將 Azure 和其他資料服務連接到 Microsoft Fabric 和 Power Platform,以便安全地與數據源通信、執行查詢並將結果傳輸回服務。", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "id": "F01.09", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "中等", + "subcategory": "", + "text": "配置並使用本地數據閘道或 Vnet 資料閘道連接到本地或虛擬網路後面的源", + "waf": "安全" + }, { "category": "", "description": "通過使用 Azure 專用連結,可以通過專用終結點連接到 Azure 中的各種平臺即服務 (PaaS) 部署。專用終結點是特定虛擬網路和子網中的專用IP位址", "guid": "b47a393a-0804-4272-a479-8b1578b219a4", "id": "G01.01", "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", "severity": "中等", "subcategory": "", - "text": "配置專用連結以連接到客戶 Vnet 和數據工廠中的源" + "text": "配置專用連結以連接到客戶 Vnet 和數據工廠中的源", + "waf": "安全" }, { "category": "數據保護", @@ -301,7 +700,8 @@ "service": "Azure Data Factory", "severity": "中等", "subcategory": "", - "text": "在管道活動中使用 Azure Key Vault 機密" + "text": "在管道活動中使用 Azure Key Vault 機密", + "waf": "安全" }, { "category": "數據保護", @@ -312,7 +712,8 @@ "service": "Azure Data Factory", "severity": "中等", "subcategory": "", - "text": "使用 Azure 數據工廠中的 SHIR 數據儲存加密本地憑據" + "text": "使用 Azure 數據工廠中的 SHIR 數據儲存加密本地憑據", + "waf": "安全" }, { "category": "身份和訪問管理", @@ -636,9 +1037,11 @@ "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", "id": "P01.01", "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", "severity": "高", "subcategory": "", - "text": "限制工作區管理員" + "text": "限制工作區管理員", + "waf": "安全" }, { "category": "身份和訪問管理", @@ -657,7 +1060,8 @@ "id": "R01.01", "severity": "高", "subcategory": "", - "text": "如果定期使用金鑰,請重新生成/輪換金鑰" + "text": "如果定期使用金鑰,請重新生成/輪換金鑰", + "waf": "安全" }, { "category": "身份和訪問管理", @@ -745,7 +1149,7 @@ "metadata": { "name": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "state": "Preview", - "timestamp": "October 21, 2024", + "timestamp": "October 23, 2024", "waf": "Security" }, "severities": [ diff --git a/checklists/redis_checklist.en.json b/checklists/redis_checklist.en.json index c171a52b..5d2b1fb4 100644 --- a/checklists/redis_checklist.en.json +++ b/checklists/redis_checklist.en.json @@ -130,6 +130,6 @@ "name": "Redis Resiliency checklist", "state": "Preview", "waf": "Reliability", - "timestamp": "March 25, 2024" + "timestamp": "October 23, 2024" } } \ No newline at end of file diff --git a/checklists/redis_checklist.es.json b/checklists/redis_checklist.es.json index 86d43900..5fddbe88 100644 --- a/checklists/redis_checklist.es.json +++ b/checklists/redis_checklist.es.json @@ -4,13 +4,13 @@ "name": "Gestión de identidades y accesos" }, { - "name": "Topología y conectividad de red" + "name": "Topología de red y conectividad" }, { - "name": "BC y DR" + "name": "BC y RD" }, { - "name": "Gobernanza y seguridad" + "name": "Gobernabilidad y seguridad" }, { "name": "Gobernanza de costos" @@ -24,40 +24,40 @@ ], "items": [ { - "category": "BC y DR", + "category": "BC y RD", "guid": "65285269-440b-44be-9d3e-0844276d4bdc", "id": "A01.01", "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", "service": "Redis", "severity": "Alto", "subcategory": "Alta disponibilidad", - "text": "Habilite la redundancia de zona para Azure Cache for Redis. Azure Cache for Redis admite configuraciones con redundancia de zona en los niveles Premium y Enterprise. Una caché con redundancia de zona puede colocar sus nodos en diferentes zonas de disponibilidad de Azure en la misma región. Elimina la interrupción del centro de datos o de la zona de disponibilidad como único punto de error y aumenta la disponibilidad general de la memoria caché.", + "text": "Habilite la redundancia de zona para Azure Cache for Redis. Azure Cache for Redis admite configuraciones con redundancia de zona en los niveles Premium y Enterprise. Una caché con redundancia de zona puede colocar sus nodos en diferentes zonas de disponibilidad de Azure en la misma región. Elimina la interrupción del centro de datos o de la zona de disponibilidad como único punto de error y aumenta la disponibilidad general de la caché.", "waf": "Fiabilidad" }, { - "category": "BC y DR", + "category": "BC y RD", "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", "id": "A01.02", "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", "service": "Redis", "severity": "Medio", "subcategory": "Alta disponibilidad", - "text": "Configure la persistencia de datos para una instancia de Azure Cache for Redis. Dado que los datos de caché se almacenan en la memoria, un error poco frecuente y no planeado de varios nodos puede hacer que se eliminen todos los datos. Para evitar la pérdida completa de datos, la persistencia de Redis permite tomar instantáneas periódicas de los datos en memoria y almacenarlas en la cuenta de almacenamiento.", + "text": "Configure la persistencia de datos para una instancia de Azure Cache for Redis. Dado que los datos de caché se almacenan en la memoria, un error poco frecuente y no planeado de varios nodos puede hacer que se eliminen todos los datos. Para evitar la pérdida total de datos, la persistencia de Redis le permite tomar instantáneas periódicas de datos en memoria y almacenarlas en su cuenta de almacenamiento.", "waf": "Fiabilidad" }, { - "category": "BC y DR", + "category": "BC y RD", "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", "id": "A01.03", "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", "service": "Redis", "severity": "Medio", "subcategory": "Alta disponibilidad", - "text": "Use una cuenta de almacenamiento con redundancia geográfica para conservar los datos de Azure Cache for Redis o con redundancia zonal donde la redundancia geográfica no esté disponible", + "text": "Use la cuenta de almacenamiento con redundancia geográfica para conservar los datos de Azure Cache for Redis o con redundancia zonal donde la redundancia geográfica no esté disponible", "waf": "Fiabilidad" }, { - "category": "BC y DR", + "category": "BC y RD", "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", "id": "A01.04", "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", @@ -71,7 +71,7 @@ "metadata": { "name": "Redis Resiliency checklist", "state": "Preview", - "timestamp": "March 25, 2024", + "timestamp": "October 23, 2024", "waf": "Reliability" }, "severities": [ @@ -99,7 +99,7 @@ "name": "Cumplido" }, { - "description": "Recomendación entendida, pero no necesaria por los requisitos actuales", + "description": "Recomendación comprendida, pero no necesaria por los requisitos actuales", "name": "No es necesario" }, { diff --git a/checklists/redis_checklist.ja.json b/checklists/redis_checklist.ja.json index 367d68c1..6def16b2 100644 --- a/checklists/redis_checklist.ja.json +++ b/checklists/redis_checklist.ja.json @@ -1,13 +1,13 @@ { "categories": [ { - "name": "IDおよびアクセス管理" + "name": "ID およびアクセス管理" }, { - "name": "ネットワークトポロジと接続性" + "name": "ネットワーク トポロジと接続性" }, { - "name": "BCとDR" + "name": "BC と DR" }, { "name": "ガバナンスとセキュリティ" @@ -19,59 +19,59 @@ "name": "オペレーションズ" }, { - "name": "アプリケーションの展開" + "name": "アプリケーションのデプロイメント" } ], "items": [ { - "category": "BCとDR", + "category": "BC と DR", "guid": "65285269-440b-44be-9d3e-0844276d4bdc", "id": "A01.01", "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", "service": "Redis", "severity": "高い", "subcategory": "高可用性", - "text": "Azure Cache for Redis のゾーン冗長を有効にします。Azure Cache for Redis では、Premium レベルと Enterprise レベルでゾーン冗長構成がサポートされています。ゾーン冗長キャッシュでは、同じリージョン内の異なる Azure Availability Zones にノードを配置できます。これにより、データセンターや AZ の停止が単一障害点として排除され、キャッシュの全体的な可用性が向上します。", + "text": "Azure Cache for Redis のゾーン冗長を有効にします。Azure Cache for Redis では、Premium レベルと Enterprise レベルでのゾーン冗長構成がサポートされています。ゾーン冗長キャッシュは、同じリージョン内の異なる Azure Availability Zones にノードを配置できます。これにより、データセンターや AZ の障害点としての停止が排除され、キャッシュの全体的な可用性が向上します。", "waf": "確実" }, { - "category": "BCとDR", + "category": "BC と DR", "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", "id": "A01.02", "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", "service": "Redis", "severity": "中程度", "subcategory": "高可用性", - "text": "Azure Cache for Redis インスタンスのデータ永続化を構成します。キャッシュ データはメモリに格納されるため、まれに複数のノードで計画外の障害が発生すると、すべてのデータがドロップされる可能性があります。データの完全な損失を回避するために、Redis 永続化では、メモリ内データのスナップショットを定期的に取得し、ストレージ アカウントに格納できます。", + "text": "Azure Cache for Redis インスタンスのデータ永続化を構成します。キャッシュ データはメモリに格納されるため、まれに複数のノードで予期しない障害が発生すると、すべてのデータがドロップされる可能性があります。データが完全に失われないように、Redis 永続化では、メモリ内データのスナップショットを定期的に作成し、それをストレージ アカウントに格納できます。", "waf": "確実" }, { - "category": "BCとDR", + "category": "BC と DR", "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", "id": "A01.03", "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", "service": "Redis", "severity": "中程度", "subcategory": "高可用性", - "text": "geo 冗長ストレージ アカウントを使用して Azure Cache for Redis データを保持するか、geo 冗長性を使用できない場合はゾーン冗長を使用します", + "text": "Geo 冗長ストレージ アカウントを使用して Azure Cache for Redis データを保持するか、geo 冗長性を使用できない場合はゾーン冗長を使用します", "waf": "確実" }, { - "category": "BCとDR", + "category": "BC と DR", "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", "id": "A01.04", "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", "service": "Redis", "severity": "中程度", "subcategory": "高可用性", - "text": "Premium Azure Cache for Redis インスタンスのパッシブ geo レプリケーションを構成します。geo レプリケーションは、2 つ以上の Azure Cache for Redis インスタンス (通常は 2 つの Azure リージョンにまたがる) をリンクするためのメカニズムです。geo レプリケーションは、主にリージョン間のディザスター リカバリー用に設計されています。2 つの Premium レベルのキャッシュ インスタンスは、プライマリ キャッシュへの読み取りと書き込みを提供する方法で geo レプリケーションを介して接続され、そのデータはセカンダリ キャッシュにレプリケートされます。", + "text": "Premium Azure Cache for Redis インスタンスのパッシブ geo レプリケーションを構成します。geo レプリケーションは、2 つ以上の Azure Cache for Redis インスタンス (通常は 2 つの Azure リージョンにまたがる) をリンクするためのメカニズムです。geo レプリケーションは、主にリージョン間のディザスター リカバリー用に設計されています。2 つの Premium レベルのキャッシュ インスタンスは、プライマリ キャッシュに対して読み取りと書き込みを提供する方法で geo レプリケーションを介して接続され、そのデータはセカンダリ キャッシュにレプリケートされます。", "waf": "確実" } ], "metadata": { "name": "Redis Resiliency checklist", "state": "Preview", - "timestamp": "March 25, 2024", + "timestamp": "October 23, 2024", "waf": "Reliability" }, "severities": [ @@ -87,7 +87,7 @@ ], "status": [ { - "description": "このチェックはまだ検討されていません", + "description": "このチェックはまだ見ていません", "name": "未確認" }, { @@ -95,12 +95,12 @@ "name": "開ける" }, { - "description": "このチェックは検証済みで、これ以上のアクションアイテムは関連付けられていません", + "description": "このチェックは検証済みであり、これ以上のアクション アイテムは関連付けられていません", "name": "達成" }, { - "description": "推奨事項は理解されているが、現在の要件では不要", - "name": "必要なし" + "description": "推奨事項は理解されているが、現在の要件では必要ではない", + "name": "必須ではありません" }, { "description": "現在のデザインには適用されません", diff --git a/checklists/redis_checklist.ko.json b/checklists/redis_checklist.ko.json index 7affedf7..a4aabd56 100644 --- a/checklists/redis_checklist.ko.json +++ b/checklists/redis_checklist.ko.json @@ -13,7 +13,7 @@ "name": "거버넌스 및 보안" }, { - "name": "비용 거버넌스" + "name": "비용 관리" }, { "name": "작업" @@ -31,7 +31,7 @@ "service": "Redis", "severity": "높다", "subcategory": "고가용성", - "text": "Azure Cache for Redis에 대한 영역 중복성을 사용하도록 설정합니다. Azure Cache for Redis는 프리미엄 및 엔터프라이즈 계층에서 영역 중복 구성을 지원합니다. 영역 중복 캐시는 동일한 지역의 여러 Azure 가용성 영역에 노드를 배치할 수 있습니다. 데이터 센터 또는 AZ 중단을 단일 장애 지점으로 제거하고 캐시의 전반적인 가용성을 높입니다.", + "text": "Azure Cache for Redis에 대한 영역 중복을 사용하도록 설정합니다. Azure Cache for Redis는 프리미엄 및 엔터프라이즈 계층에서 영역 중복 구성을 지원합니다. 영역 중복 캐시는 동일한 지역의 여러 Azure 가용성 영역에 노드를 배치할 수 있습니다. 데이터 센터 또는 AZ 중단을 단일 장애 지점으로 제거하고 캐시의 전반적인 가용성을 높입니다.", "waf": "신뢰도" }, { @@ -42,7 +42,7 @@ "service": "Redis", "severity": "보통", "subcategory": "고가용성", - "text": "Azure Cache for Redis 인스턴스에 대한 데이터 지속성을 구성합니다. 캐시 데이터는 메모리에 저장되기 때문에 드물게 계획되지 않은 여러 노드의 오류로 인해 모든 데이터가 삭제될 수 있습니다. 데이터가 완전히 손실되는 것을 방지하기 위해 Redis 지속성을 사용하면 메모리 내 데이터의 주기적인 스냅숏을 만들어 저장소 계정에 저장할 수 있습니다.", + "text": "Azure Cache for Redis 인스턴스에 대한 데이터 지속성을 구성합니다. 캐시 데이터가 메모리에 저장되기 때문에 여러 노드의 드물고 계획되지 않은 오류로 인해 모든 데이터가 삭제될 수 있습니다. 데이터가 완전히 손실되는 것을 방지하기 위해 Redis 지속성을 사용하면 메모리 내 데이터의 주기적인 스냅샷을 만들고 스토리지 계정에 저장할 수 있습니다.", "waf": "신뢰도" }, { @@ -53,7 +53,7 @@ "service": "Redis", "severity": "보통", "subcategory": "고가용성", - "text": "지역 중복 스토리지 계정을 사용하여 Azure Cache for Redis 데이터를 유지하거나 지역 중복을 사용할 수 없는 경우 영역 중복을 유지합니다", + "text": "지역 중복 스토리지 계정을 사용하여 Azure Cache for Redis 데이터를 유지하거나 지역 중복을 사용할 수 없는 경우 영역 중복을 사용합니다.", "waf": "신뢰도" }, { @@ -64,14 +64,14 @@ "service": "Redis", "severity": "보통", "subcategory": "고가용성", - "text": "프리미엄 Azure Cache for Redis 인스턴스에 대한 수동 지역 복제를 구성합니다. 지역에서 복제는 일반적으로 두 개의 Azure 지역에 걸쳐 있는 둘 이상의 Azure Cache for Redis 인스턴스를 연결하는 메커니즘입니다. 지역에서 복제는 주로 지역 간 재해 복구를 위해 설계되었습니다. 두 개의 프리미엄 계층 캐시 인스턴스는 주 캐시에 대한 읽기 및 쓰기를 제공하는 방식으로 지역 복제를 통해 연결되며, 해당 데이터는 보조 캐시에 복제됩니다.", + "text": "프리미엄 Azure Cache for Redis 인스턴스에 대한 수동 지역 복제를 구성합니다. 지역에서 복제는 일반적으로 두 개의 Azure 지역에 걸쳐 있는 두 개 이상의 Azure Cache for Redis 인스턴스를 연결하는 메커니즘입니다. 지역에서 복제는 주로 지역 간 재해 복구를 위해 설계되었습니다. 두 개의 프리미엄 계층 캐시 인스턴스는 주 캐시에 대한 읽기 및 쓰기를 제공하는 방식으로 지역 복제를 통해 연결되며, 해당 데이터는 보조 캐시에 복제됩니다.", "waf": "신뢰도" } ], "metadata": { "name": "Redis Resiliency checklist", "state": "Preview", - "timestamp": "March 25, 2024", + "timestamp": "October 23, 2024", "waf": "Reliability" }, "severities": [ @@ -99,7 +99,7 @@ "name": "성취" }, { - "description": "권장 사항은 이해되었지만 현재 요구 사항에 필요하지 않음", + "description": "권장 사항을 이해했지만 현재 요구 사항에 필요하지 않음", "name": "필요 없음" }, { diff --git a/checklists/redis_checklist.pt.json b/checklists/redis_checklist.pt.json index 4f69d346..c279bb62 100644 --- a/checklists/redis_checklist.pt.json +++ b/checklists/redis_checklist.pt.json @@ -1,19 +1,19 @@ { "categories": [ { - "name": "Gerenciamento de identidades e acesso" + "name": "Gerenciamento de identidade e acesso" }, { - "name": "Topologia de rede e conectividade" + "name": "Topologia e conectividade de rede" }, { "name": "BC e DR" }, { - "name": "Governança e Segurança" + "name": "Governança e segurança" }, { - "name": "Governança de Custos" + "name": "Governança de custos" }, { "name": "Operações" @@ -30,8 +30,8 @@ "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", "service": "Redis", "severity": "Alto", - "subcategory": "Alta Disponibilidade", - "text": "Habilite a redundância de zona para o Cache do Azure para Redis. O Cache do Azure para Redis dá suporte a configurações redundantes de zona nas camadas Premium e Enterprise. Um cache redundante de zona pode colocar seus nós em diferentes zonas de disponibilidade do Azure na mesma região. Ele elimina a interrupção do data center ou AZ como um único ponto de falha e aumenta a disponibilidade geral do cache.", + "subcategory": "Alta disponibilidade", + "text": "Habilite a redundância de zona para o Cache do Azure para Redis. O Cache do Azure para Redis dá suporte a configurações com redundância de zona nas camadas Premium e Enterprise. Um cache com redundância de zona pode colocar seus nós em diferentes Zonas de Disponibilidade do Azure na mesma região. Ele elimina a interrupção do data center ou da AZ como um único ponto de falha e aumenta a disponibilidade geral do cache.", "waf": "Fiabilidade" }, { @@ -41,8 +41,8 @@ "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", "service": "Redis", "severity": "Média", - "subcategory": "Alta Disponibilidade", - "text": "Configure a persistência de dados para uma instância do Cache do Azure para Redis. Como os dados do cache são armazenados na memória, uma falha rara e não planejada de vários nós pode fazer com que todos os dados sejam descartados. Para evitar a perda completa de dados, a persistência do Redis permite que você tire instantâneos periódicos de dados na memória e os armazene em sua conta de armazenamento.", + "subcategory": "Alta disponibilidade", + "text": "Configure a persistência de dados para uma instância do Cache do Azure para Redis. Como os dados de cache são armazenados na memória, uma falha rara e não planejada de vários nós pode fazer com que todos os dados sejam descartados. Para evitar a perda completa de dados, a persistência do Redis permite que você tire instantâneos periódicos de dados na memória e armazene-os em sua conta de armazenamento.", "waf": "Fiabilidade" }, { @@ -52,8 +52,8 @@ "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", "service": "Redis", "severity": "Média", - "subcategory": "Alta Disponibilidade", - "text": "Use a conta de armazenamento com redundância geográfica para persistir o Cache do Azure para dados Redis ou zonalmente redundante onde a redundância geográfica não está disponível", + "subcategory": "Alta disponibilidade", + "text": "Use a conta de armazenamento com redundância geográfica para manter os dados do Cache do Azure para Redis ou com redundância zonal em que a redundância geográfica não está disponível", "waf": "Fiabilidade" }, { @@ -63,15 +63,15 @@ "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", "service": "Redis", "severity": "Média", - "subcategory": "Alta Disponibilidade", - "text": "Configure a replicação geográfica passiva para instâncias do Cache Premium do Azure para Redis. A replicação geográfica é um mecanismo para vincular duas ou mais instâncias do Cache do Azure para Redis, normalmente abrangendo duas regiões do Azure. A replicação geográfica foi projetada principalmente para recuperação de desastres entre regiões. Duas instâncias de cache de camada Premium são conectadas por meio de replicação geográfica de uma forma que fornece leituras e gravações no cache primário e que os dados são replicados para o cache secundário.", + "subcategory": "Alta disponibilidade", + "text": "Configure a replicação geográfica passiva para instâncias do Cache do Azure Premium para Redis. A replicação geográfica é um mecanismo para vincular duas ou mais instâncias do Cache do Azure para Redis, normalmente abrangendo duas regiões do Azure. A replicação geográfica foi projetada principalmente para recuperação de desastres entre regiões. Duas instâncias de cache da camada Premium são conectadas por meio da replicação geográfica de uma forma que fornece leituras e gravações no cache primário e esses dados são replicados para o cache secundário.", "waf": "Fiabilidade" } ], "metadata": { "name": "Redis Resiliency checklist", "state": "Preview", - "timestamp": "March 25, 2024", + "timestamp": "October 23, 2024", "waf": "Reliability" }, "severities": [ @@ -95,7 +95,7 @@ "name": "Abrir" }, { - "description": "Essa verificação foi verificada e não há outros itens de ação associados a ela", + "description": "Essa verificação foi verificada e não há mais itens de ação associados a ela", "name": "Cumprido" }, { @@ -103,7 +103,7 @@ "name": "Não é necessário" }, { - "description": "Não aplicável ao projeto atual", + "description": "Não aplicável para o projeto atual", "name": "N/A" } ], diff --git a/checklists/redis_checklist.zh-Hant.json b/checklists/redis_checklist.zh-Hant.json index eaf9f230..b4ef8f05 100644 --- a/checklists/redis_checklist.zh-Hant.json +++ b/checklists/redis_checklist.zh-Hant.json @@ -10,7 +10,7 @@ "name": "BC 和DR" }, { - "name": "治理與安全" + "name": "治理和安全" }, { "name": "成本治理" @@ -31,7 +31,7 @@ "service": "Redis", "severity": "高", "subcategory": "高可用性", - "text": "為 Azure Cache for Redis 啟用區域冗餘。Azure Cache for Redis 支持高級層和企業層中的區域冗餘配置。區域冗餘緩存可以將其節點放置在同一區域的不同 Azure 可用性區域中。它消除了作為單點故障的數據中心或可用區中斷,並提高了緩存的整體可用性。", + "text": "為 Azure Cache for Redis 啟用區域冗餘。Azure Cache for Redis 支持高級層和企業層中的區域冗餘配置。區域冗餘緩存可以將其節點放置在同一區域的不同 Azure 可用性區域中。它消除了數據中心或可用區中斷作為單點故障,並提高了緩存的整體可用性。", "waf": "可靠性" }, { @@ -42,7 +42,7 @@ "service": "Redis", "severity": "中等", "subcategory": "高可用性", - "text": "為 Azure Cache for Redis 實例配置數據持久性。由於緩存數據存儲在記憶體中,因此多個節點的罕見和計劃外故障可能會導致所有數據被丟棄。為了避免完全丟失數據,Redis 持久性允許您定期拍攝記憶體中數據的快照,並將其存儲到存儲帳戶中。", + "text": "為 Azure Cache for Redis 實例配置數據持久性。由於緩存數據存儲在記憶體中,因此多個節點的罕見意外故障可能會導致所有數據被丟棄。為避免完全丟失數據,Redis 持久性允許您定期拍攝記憶體數據的快照,並將其存儲到您的存儲帳戶中。", "waf": "可靠性" }, { @@ -53,7 +53,7 @@ "service": "Redis", "severity": "中等", "subcategory": "高可用性", - "text": "使用異地冗餘存儲帳戶保留 Azure Cache for Redis 數據,或在異地冗餘不可用的情況下使用區域冗餘", + "text": "使用異地冗餘存儲帳戶來保存 Azure Cache for Redis 數據,或者在異地冗餘不可用的情況下使用區域冗餘", "waf": "可靠性" }, { @@ -64,14 +64,14 @@ "service": "Redis", "severity": "中等", "subcategory": "高可用性", - "text": "為高級 Azure Cache for Redis 實例配置被動異地複製。異地複製是一種用於連結兩個或多個 Azure Cache for Redis 實例的機制,通常跨越兩個 Azure 區域。異地複製主要用於跨區域災難恢復。兩個高級層緩存實例通過異地複製進行連接,從而提供對主緩存的讀取和寫入,並將數據複製到輔助緩存。", + "text": "為高級 Azure Cache for Redis 實例配置被動異地複製。異地複製是一種用於連結兩個或多個 Azure Cache for Redis 實例的機制,通常跨兩個 Azure 區域。異地複製主要用於跨區域災難恢復。兩個高級層緩存實例通過異地複製進行連接,以便對主緩存進行讀取和寫入,並將該數據複製到輔助緩存。", "waf": "可靠性" } ], "metadata": { "name": "Redis Resiliency checklist", "state": "Preview", - "timestamp": "March 25, 2024", + "timestamp": "October 23, 2024", "waf": "Reliability" }, "severities": [ @@ -87,19 +87,19 @@ ], "status": [ { - "description": "此檢查尚未查看", + "description": "尚未查看此檢查", "name": "未驗證" }, { - "description": "有一個與此檢查關聯的操作項", + "description": "存在與此檢查關聯的操作項", "name": "打開" }, { - "description": "此檢查已通過驗證,並且沒有與之關聯的進一步操作項", + "description": "此檢查已經過驗證,沒有與之關聯的其他操作項", "name": "實現" }, { - "description": "建議已理解,但當前需求不需要", + "description": "建議已理解,但當前要求不需要", "name": "不需要" }, { diff --git a/checklists/sqldb_checklist.en.json b/checklists/sqldb_checklist.en.json index bc8e0811..46718e26 100644 --- a/checklists/sqldb_checklist.en.json +++ b/checklists/sqldb_checklist.en.json @@ -1,641 +1,641 @@ { - "items": [ - { - "category": "BCDR", - "subcategory": "Azure Key Vault", - "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", - "description": "Ensure that your backups are protected against attacks. This should include encryption of the backups to protect against loss of confidentiality. For regular Azure service backup, backup data is automatically encrypted using Azure platform-managed keys. You can also choose to encrypt the backup using a customer-managed key. In this case, ensure this customer-managed key in the key vault is also in the backup scope.", - "waf": "Security", - "guid": "676f6951-0368-49e9-808d-c33a692c9a64", - "id": "A01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data" - }, - { - "category": "BCDR", - "subcategory": "Backup", - "text": "Configure Azure SQL Database automated backups", - "description": "Azure SQL Database uses SQL Server technology to create full backups every week, differential backup every 12-24 hours, and transaction log backup every 5 to 10 minutes. By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region.", - "waf": "Security", - "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", - "id": "A02.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups" - }, - { - "category": "BCDR", - "subcategory": "Backup", - "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", - "description": "By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region. For SQL Database, the backup storage redundancy can be configured at the time of database creation or can be updated for an existing database; the changes made to an existing database apply to future backups only.", - "waf": "Security", - "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", - "id": "A02.02", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy" - }, - { - "category": "Code", - "subcategory": "Source Control and Code Review", - "text": "Use Source Control systems to store, maintain and review application code deployed inside Azure SQLDB Database", - "description": "Malicious code can potentially circumvent security controls. Before deploying custom code to production, it is essential to review what's being deployed. Use a database tool like Azure Data Studio that supports source control. Implement tools and logic for code analysis, vulnerability and credential scanning.", - "waf": "Security", - "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", - "id": "B01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server" - }, - { - "category": "Data Discovery and Classification", - "subcategory": "Data Discovery and Classification", - "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", - "description": "In case of classification requirements Purview is the preferred option. Only use SQL Data Discovery & Classification in case Purview is not an option. Discover columns that potentially contain sensitive data. What is considered sensitive data heavily depends on the customer, compliance regulation, etc., and needs to be evaluated by the users in charge of that data. Classify the columns to use advanced sensitivity-based auditing and protection scenarios. Review results of automated discovery and finalize the classification if necessary.", - "waf": "Security", - "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", - "id": "C01.01", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities" - }, - { - "category": "Data Masking", - "subcategory": "Data Masking", - "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible", - "description": "Usage of this feature is recommended only if column encryption is not an option and there is a specific requirement to preserve data types and formats. Dynamic data masking limits sensitive data exposure by masking it to non-privileged users. Dynamic data masking helps prevent unauthorized access to sensitive data by enabling customers to designate how much of the sensitive data to reveal with minimal impact on the application layer.", - "waf": "Security", - "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", - "id": "D01.01", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview" - }, - { - "category": "Defender", - "subcategory": "Advanced Threat Protection", - "text": "Review and complete Advanced Threat Protection (ATP) configuration", - "description": "SQL Advanced Threat Detection (ATP) provides a layer of security that detects potential vulnerabilities and anomalous activity in databases such as SQL injection attacks and unusual behavior patterns. When a potential threat is detected Threat Detection sends an actionable real-time alert by email and in Microsoft Defender for Cloud, which includes clear investigation and remediation steps for the specific threat.", - "waf": "Security", - "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", - "id": "E01.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure" - }, - { - "category": "Defender", - "subcategory": "Defender for Azure SQL", - "text": "Enable Microsoft Defender for Azure SQL", - "description": "Enable Microsoft Defender for Azure SQL at the subscription level to automatically onboard and protect all existing and future servers and databases. When you enable on the subscription level, all databases in Azure SQL Database and Azure SQL Managed Instance are protected. You can then disable them individually if you choose. If you want to manually manage which databases are protected, disable at the subscription level and enable each database that you want protected.", - "waf": "Security", - "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", - "id": "E02.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql " - }, - { - "category": "Defender", - "subcategory": "Defender for Azure SQL", - "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", - "description": "Microsoft Defender for Azure SQL ATP detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. Alerts can be configured and generated and will be reported in the Defender for console.", - "waf": "Security", - "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", - "id": "E02.02", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure" - }, - { - "category": "Defender", - "subcategory": "Vulnerability Assessment", - "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", - "description": "Azure SQLDB vulnerability assessment is a service that provides visibility into your security state. Vulnerability assessment includes actionable steps to resolve security issues and enhance your database security. It can help you to monitor a dynamic database environment where changes are difficult to track and improve your SQL security posture.", - "waf": "Security", - "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", - "id": "E03.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview" - }, - { - "category": "Defender", - "subcategory": "Vulnerability Assessment", - "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", - "description": "Microsoft Defender for Cloud provides vulnerability assessment for your Azure SQL Databases. Vulnerability assessment scans your databases for software vulnerabilities and provides a list of findings. You can use the findings to remediate software vulnerabilities and disable findings.", - "waf": "Security", - "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", - "id": "E03.02", - "severity": "High", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql" - }, - { - "category": "Encryption", - "subcategory": "Always Encrypted", - "text": "If protecting sensitive PII data from admin users is a key requirement, but Column Encryption limitations cannot be tolerated, consider the adoption of Always Encrypted with Secure Enclaves", - "description": "Always Encrypted with Secure Enclaves expands confidential computing capabilities of Always Encrypted by enabling in-place encryption and richer confidential queries. Always Encrypted with Secure Enclaves addresses these limitations by allowing some computations on plaintext data inside a secure enclave on the server side. Usage of this feature is recommended for the cases where you need to limit administrator access and need your queries to support more than equality matching of encrypted columns.", - "waf": "Security", - "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", - "id": "F01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves" - }, - { - "category": "Encryption", - "subcategory": "Column Encryption", - "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption", - "description": "With Azure SQL Database, you can apply symmetric encryption to a column of data by using Transact-SQL. This approach is called column encryption, because you can use it to encrypt specific columns with different encryption keys. Doing so gives you more granular encryption capability than TDE, which encrypts data in pages. Using Always Encrypted to ensure sensitive data isn't exposed in plaintext in Azure SQL Database or SQL Managed Instance, even in memory/in use. Always Encrypted protects the data from Database Administrators (DBAs) and cloud admins (or bad actors who can impersonate high-privileged but unauthorized users) and gives you more control over who can access your data.", - "waf": "Security", - "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", - "id": "F02.01", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption" - }, - { - "category": "Encryption", - "subcategory": "Transparent Data Encryption", - "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", - "description": "Enabled by default, Transparent data encryption (TDE) helps to protect the database files against information disclosure by performing real-time encryption and decryption of the database, associated backups, and transaction log files 'at rest', without requiring changes to the application.", - "waf": "Security", - "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", - "id": "F03.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server" - }, - { - "category": "Encryption", - "subcategory": "Transparent Data Encryption", - "text": "Use customer-managed keys (CMK) in Azure Key Vault (AKV) if you need increased transparency and granular control over the TDE protection", - "description": "If separation of duties in the management of keys and data within the organization is required, leverage Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) for your Azure SQLDB and use Azure Key Vault to store (refer to its checklist). Leverage this feature when you have strict security requirements which cannot be met by the managed service keys.", - "waf": "Security", - "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", - "id": "F03.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview" - }, - { - "category": "Encryption", - "subcategory": "Transport Layer Security", - "text": "Enforce minimum TLS version to the latest available", - "description": "The minimal Transport Layer Security (TLS) version setting allows customers to choose which version of TLS their SQL database uses. It's possible to change the minimum TLS version by using the Azure portal, Azure PowerShell, and the Azure CLI.", - "waf": "Security", - "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", - "id": "F04.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version" - }, - { - "category": "Identity", - "subcategory": "Azure Active Directory", - "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", - "description": "Use Azure Active Directory (Azure AD) authentication for centralized identity management. Use SQL Authentication only if really necessary and document as exceptions.", - "waf": "Security", - "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", - "id": "G01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview" - }, - { - "category": "Identity", - "subcategory": "Azure Active Directory", - "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server", - "description": "Using Azure AD groups simplifies permission management and both the group owner, and the resource owner can add/remove members to/from the group. Create a separate group for Azure AD administrators for each logical server. Monitor Azure AD group membership changes using Azure AD audit activity reports.", - "waf": "Security", - "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", - "id": "G01.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities" - }, - { - "category": "Identity", - "subcategory": "Azure Active Directory", - "text": "Minimize the use of password-based authentication for applications", - "description": "Ensure that distinct system and user assigned managed identities, that are dedicated to the function, with least permissions assigned, are used for communication from Azure services and applications to the Azure SQLDB databases.", - "waf": "Security", - "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", - "id": "G01.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications" - }, - { - "category": "Identity", - "subcategory": "Managed Identities", - "text": "Assign Azure SQL Database a managed identity for outbound resource access", - "description": "System or User assigned managed identities enable Azure SQLDB to authenticate to other cloud services (e.g. Azure Key Vault) without storing credentials in code. Once enabled, all necessary permissions can be granted via Azure role-based-access-control to the specific Azure SQLDB instance. Do not share user assigned managed identities across multiple services if not strictly required.", - "waf": "Security", - "guid": "69891194-5074-4e30-8f69-4efc3c580900", - "id": "G02.01", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview" - }, - { - "category": "Identity", - "subcategory": "Passwords", - "text": "Minimize the use of password-based authentication for users", - "description": "Use an Azure AD integrated authentication that eliminates the use of passwords. Password-based authentication methods are a weaker form of authentication. Credentials can be compromised or mistakenly given away. Use single sign-on authentication using Windows credentials. Federate the on-premises AD domain with Azure AD and use integrated Windows authentication (for domain-joined machines with Azure AD).", - "waf": "Security", - "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", - "id": "G03.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication" - }, - { - "category": "Ledger", - "subcategory": "Database Digest", - "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", - "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Confidential Ledger is one of the supported store, it can be used and supports automatic generation and storage of database digests. Azure Ledger provides advanced security features like Blockchain Ledger Proof and Confidential Hardware Enclaves. Use it only if advanced security features are required, otherwise revert to Azure storage.", - "waf": "Security", - "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", - "id": "H01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage" - }, - { - "category": "Ledger", - "subcategory": "Database Digest", - "text": "If Azure storage account is used to store database digests, ensure security is properly configured", - "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Blob Storage with Immutable Storage feature can be used and supports automatic generation and storage of database digests. To prevent tampering of your digest files, configure and lock a retention policy for your container.", - "waf": "Security", - "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", - "id": "H01.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management" - }, - { - "category": "Ledger", - "subcategory": "Integrity", - "text": "Schedule the Ledger verification process regularly to verify data integrity", - "description": "Ledger provides a form of data integrity called forward integrity, which provides evidence of data tampering on data in your ledger tables. The database verification process takes as input one or more previously generated database digests. It then recomputes the hashes stored in the database ledger based on the current state of the ledger tables. If the computed hashes don't match the input digests, the verification fails. The failure indicates that the data has been tampered with. The verification process reports all inconsistencies that it detects.", - "waf": "Security", - "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", - "id": "H02.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification" - }, - { - "category": "Ledger", - "subcategory": "Ledger", - "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", - "description": "The Ledger feature provides tamper-evidence capabilities in your database. You can cryptographically attest to other parties, such as auditors or other business parties, that your data hasn't been tampered with. Ledger helps protect data from any attacker or high-privileged user, including database administrators (DBAs), system administrators, and cloud administrators.", - "waf": "Security", - "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", - "id": "H03.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview" - }, - { - "category": "Ledger", - "subcategory": "Recovery", - "text": "Prepare a response plan to investigate and repair a database after a tampering event", - "description": "Depending on the type of tampering, there are cases where you can repair the ledger without losing data. In the article contained in the --More Info-- column, different scenarios and recovery techniques are described.", - "waf": "Security", - "guid": "804fc554-6554-4842-91c1-713b32f99902", - "id": "H04.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering" - }, - { - "category": "Logging", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", - "description": "Azure SQL Database Auditing tracks database events and writes them to an audit log in your Azure storage account. Auditing helps you understand database activity and gain insight into discrepancies and anomalies that could indicate business concerns or suspected security violations as well as helps you meet regulatory compliance. By default auditing policy includes all actions (queries, stored procedures and successful and failed logins) against the databases, which may result in high volume of audit logs. It's recommended for customers to configure auditing for different types of actions and action groups using PowerShell.", - "waf": "Security", - "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", - "id": "I01.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview" - }, - { - "category": "Logging", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", - "description": "Azure SQL Database Auditing logs can be written to external storage accounts, Log Analytics workspace or Event Hub. Be sure to protect the target repository using backups and secured configuration. Use Azure SQL Database Managed Identity to access the storage and set an explicit retention period. Do not grant permissions to administrators to the audit log repository. Use a different target storage for --Enabling Auditing of Microsoft support operations--. ", - "waf": "Security", - "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", - "id": "I01.02", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview" - }, - { - "category": "Logging", - "subcategory": "Auditing", - "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", - "description": "The Azure Monitor activity log is a platform log in Azure that provides insight into subscription-level events. The activity log includes information like when a resource is modified. It is recommended to send this activity log to the same external storage repository as the Azure SQL Database Audit Log (storage account, Log Analytics workspace, Event Hub).", - "waf": "Security", - "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", - "id": "I01.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log" - }, - { - "category": "Logging", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", - "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR). Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", - "waf": "Security", - "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", - "id": "I02.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview" - }, - { - "category": "Logging", - "subcategory": "SIEM/SOAR", - "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", - "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR), which can be used to set up custom threat detections. Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", - "waf": "Security", - "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", - "id": "I02.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log" - }, - { - "category": "Logging", - "subcategory": "SIEM/SOAR", - "text": "Ensure that you have response plans for malicious or aberrant audit logging events", - "description": "Security Operation Center (SOC) team should create an incident response plan (playbooks or manual responses) to investigate and mitigate tampering, malicious activities, and other anomalous behaviors.", - "waf": "Security", - "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", - "id": "I02.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log" - }, - { - "category": "Networking", - "subcategory": "Connectivity", - "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", - "description": "When you create a logical server from the Azure portal for Azure SQL Database, the result is a public endpoint that is visible and reachable over the public network (Public Access). You can then limit connectivity based on firewall rules and Service Endpoint. You can also configure private connectivity only limiting connections to internal networks using Private Endpoint (Private Access). Private Access using Private Endpoint should be the default unless a business case or performance/technical reason applies that cannot support it. Usage of Private Endpoints has performance implications that need to be considered and assessed.", - "waf": "Security", - "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", - "id": "J01.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview" - }, - { - "category": "Networking", - "subcategory": "Connectivity", - "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", - "description": "IMPORTANT: Connections to private endpoint only support Proxy as the connection policy. When using private endpoints connections are proxied via the Azure SQL Database gateway to the database nodes. Clients will not have a direct connection.", - "waf": "Security", - "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", - "id": "J01.02", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture" - }, - { - "category": "Networking", - "subcategory": "Connectivity", - "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", - "description": "This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers. If you select this option, make sure that your login and user permissions limit access to authorized users only. If not strictly required, keep this setting to OFF.", - "waf": "Security", - "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", - "id": "J01.03", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview" - }, - { - "category": "Networking", - "subcategory": "Outbound Control", - "text": "Block or restrict outbound REST API calls to external endpoints", - "description": "Azure SQL Database has a new built-in feature that allows native integration with external REST endpoints. This means that integration of Azure SQL Database with Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management and in general any REST or even GraphQL endpoint. If not properly restricted, code inside an Azure SQL Database database could leverage this mechanism to exfiltrate data. If not strictly required, it is recommended to block or restrict this feature using Outbound Firewall Rules.", - "waf": "Security", - "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", - "id": "J02.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql" - }, - { - "category": "Networking", - "subcategory": "Outbound Control", - "text": "If outbound network access is required, it is recommended to configure outbound networking restrictions using built-in Azure SQL Database control feature", - "description": "Outbound firewall rules limit network traffic from the Azure SQL Database logical server to a customer defined list of Azure Storage accounts and Azure SQL Database logical servers. Any attempt to access storage accounts or databases not in this list is denied.", - "waf": "Security", - "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", - "id": "J02.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview" - }, - { - "category": "Networking", - "subcategory": "Private Access", - "text": "If Private Access connectivity is used, ensure that you are using the Private Endpoint, Azure Virtual Network, Azure Firewall, and Azure Network Security Group checklists", - "description": "Private Endpoint is created inside a subnet in an Azure Virtual Network. Proper security configuration must be applied also to the containing network environment, including NSG/ASG, UDR, firewall, monitoring and auditing.", - "waf": "Security", - "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", - "id": "J03.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server" - }, - { - "category": "Networking", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", - "description": "When adding a Private Endpoint connection, public routing to your logical server isn't blocked by default. In the --Firewall and virtual networks-- pane, the setting --Deny public network access-- is not selected by default. To disable public network access, ensure that you select --Deny public network access--.", - "waf": "Security", - "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", - "id": "J03.02", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server" - }, - { - "category": "Networking", - "subcategory": "Private Access", - "text": "If Private Endpoint (Private Access) is used, apply NSG and eventually ASG to limit incoming source IP address ranges", - "description": "Network Security Group (NSG) and Application Security Group (ASG) can be now applied to subnet containing Private Endpoints to restrict connections to Azure SQLDB based on internal source IP ranges.", - "waf": "Security", - "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", - "id": "J03.03", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints" - }, - { - "category": "Networking", - "subcategory": "Private Access", - "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet", - "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. Applications and tools that are in the same or peered virtual network in the same region could access it directly. Applications and tools that are in different region could use virtual-network-to-virtual-network connection or ExpressRoute circuit peering to establish connection. Customer should use Network Security Groups (NSG), and eventually internal firewalls, to restrict access over port 1433 only to resources that require access to a managed instance.", - "waf": "Security", - "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", - "id": "J03.04", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview" - }, - { - "category": "Networking", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", - "description": "Azure Virtual Network Service Endpoint is preferred solution if you want to establish a direct connection to the Azure SQL Database backend nodes using Redirect policy. This will allow access in high performance mode and is the recommended approach from a performance perspective.", - "waf": "Security", - "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", - "id": "J04.01", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules" - }, - { - "category": "Networking", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", - "description": "The Azure SQL Database firewall allows you to specify IP address ranges from which communications are accepted. This approach is fine for stable IP addresses that are outside the Azure private network.", - "waf": "Security", - "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", - "id": "J04.02", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview" - }, - { - "category": "Networking", - "subcategory": "Public Access", - "text": "If Public Access connectivity is used and controlled by Azure SQL Database firewall rules, use database-level over server-level IP rules", - "description": "We recommend that you use database-level IP firewall rules whenever possible. This practice enhances security and makes your database more portable. Use server-level IP firewall rules for administrators. Also use them when you have many databases that have the same access requirements, and you don't want to configure each database individually.", - "waf": "Security", - "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", - "id": "J04.03", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure" - }, - { - "category": "Networking", - "subcategory": "Public Access", - "text": "Do not enable Azure SQL Managed Instance public endpoint", - "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. The Managed Instance public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. If company policy disallows the use of public endpoints, use Azure Policy to prevent enabling public endpoints in the first place.", - "waf": "Security", - "guid": "b8435656-143e-41a8-9922-61d34edb751a", - "id": "J04.04", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview" - }, - { - "category": "Networking", - "subcategory": "Public Access", - "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", - "description": "A Managed Instance (SQL MI) public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. In this case, it is recommended to apply a Network Security Groups (NSG) to restrict access to port 3342 only to trusted source IP addresses.", - "waf": "Security", - "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", - "id": "J04.05", - "severity": "High", - "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview" - }, - { - "category": "Privileged Access", - "subcategory": "Lockbox", - "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", - "description": "Most operations, support, and troubleshooting performed by Microsoft personnel and sub-processors do not require access to customer data. In those rare circumstances where such access is required, Customer Lockbox for Microsoft Azure provides an interface for customers to review and approve or reject customer data access requests. In support scenarios where Microsoft needs to access customer data, Azure SQL Database supports Customer Lockbox to provide an interface for you to review and approve or reject customer data access requests.", - "waf": "Security", - "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", - "id": "K01.01", - "severity": "Low", - "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview" - }, - { - "category": "Privileged Access", - "subcategory": "Permissions", - "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", - "description": "The principle of least privilege states that users shouldn't have more privileges than needed to complete their tasks. High-privileged database and server users can perform many configuration and maintenance activities on the database and can also drop databases in Azure SQL instance. Tracking database owners and privileged accounts is important to avoid having excessive permission.", - "waf": "Security", - "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", - "id": "K02.01", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege" - }, - { - "category": "Privileged Access", - "subcategory": "Permissions", - "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", - "description": "Identities (both Users and SPNs) should be scoped to the least amount of access needed to perform the function. A higher number of tightly scoped SPNs should be used, instead of having one SPN with multiple sets of unrelated permissions. For example, if there are three external web applications hosted on-prem that make queries to the Azure SQL Database, they should not all use the same SPN for these activities. Instead, they should each have their own tightly scoped SPN.", - "waf": "Security", - "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", - "id": "K02.02", - "severity": "Low", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access" + "items": [ + { + "category": "BCDR", + "subcategory": "Azure Key Vault", + "text": "Protect your backup data with encryption and store keys safely in Azure Key Vault", + "description": "Ensure that your backups are protected against attacks. This should include encryption of the backups to protect against loss of confidentiality. For regular Azure service backup, backup data is automatically encrypted using Azure platform-managed keys. You can also choose to encrypt the backup using a customer-managed key. In this case, ensure this customer-managed key in the key vault is also in the backup scope.", + "waf": "Security", + "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data" + }, + { + "category": "BCDR", + "subcategory": "Backup", + "text": "Configure Azure SQL Database automated backups", + "description": "Azure SQL Database uses SQL Server technology to create full backups every week, differential backup every 12-24 hours, and transaction log backup every 5 to 10 minutes. By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region.", + "waf": "Security", + "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups" + }, + { + "category": "BCDR", + "subcategory": "Backup", + "text": "Enable geo-redundant backup storage to protect against single region failure and data loss", + "description": "By default, SQL Database stores data in geo-redundant storage blobs that are replicated to a paired region. For SQL Database, the backup storage redundancy can be configured at the time of database creation or can be updated for an existing database; the changes made to an existing database apply to future backups only.", + "waf": "Security", + "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy" + }, + { + "category": "Code", + "subcategory": "Source Control and Code Review", + "text": "Use Source Control systems to store, maintain and review application code deployed inside Azure SQLDB Database", + "description": "Malicious code can potentially circumvent security controls. Before deploying custom code to production, it is essential to review what's being deployed. Use a database tool like Azure Data Studio that supports source control. Implement tools and logic for code analysis, vulnerability and credential scanning.", + "waf": "Security", + "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server" + }, + { + "category": "Data Discovery and Classification", + "subcategory": "Data Discovery and Classification", + "text": "Plan and configure Data Discovery & Classification to protect the sensitive data", + "description": "In case of classification requirements Purview is the preferred option. Only use SQL Data Discovery & Classification in case Purview is not an option. Discover columns that potentially contain sensitive data. What is considered sensitive data heavily depends on the customer, compliance regulation, etc., and needs to be evaluated by the users in charge of that data. Classify the columns to use advanced sensitivity-based auditing and protection scenarios. Review results of automated discovery and finalize the classification if necessary.", + "waf": "Security", + "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities" + }, + { + "category": "Data Masking", + "subcategory": "Data Masking", + "text": "Use Data Masking to prevent unauthorized non-admin users data access if no encryption is possible", + "description": "Usage of this feature is recommended only if column encryption is not an option and there is a specific requirement to preserve data types and formats. Dynamic data masking limits sensitive data exposure by masking it to non-privileged users. Dynamic data masking helps prevent unauthorized access to sensitive data by enabling customers to designate how much of the sensitive data to reveal with minimal impact on the application layer.", + "waf": "Security", + "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview" + }, + { + "category": "Defender", + "subcategory": "Advanced Threat Protection", + "text": "Review and complete Advanced Threat Protection (ATP) configuration", + "description": "SQL Advanced Threat Detection (ATP) provides a layer of security that detects potential vulnerabilities and anomalous activity in databases such as SQL injection attacks and unusual behavior patterns. When a potential threat is detected Threat Detection sends an actionable real-time alert by email and in Microsoft Defender for Cloud, which includes clear investigation and remediation steps for the specific threat.", + "waf": "Security", + "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure" + }, + { + "category": "Defender", + "subcategory": "Defender for Azure SQL", + "text": "Enable Microsoft Defender for Azure SQL", + "description": "Enable Microsoft Defender for Azure SQL at the subscription level to automatically onboard and protect all existing and future servers and databases. When you enable on the subscription level, all databases in Azure SQL Database and Azure SQL Managed Instance are protected. You can then disable them individually if you choose. If you want to manually manage which databases are protected, disable at the subscription level and enable each database that you want protected.", + "waf": "Security", + "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql " + }, + { + "category": "Defender", + "subcategory": "Defender for Azure SQL", + "text": "Prepare a security response plan to promptly react to Microsoft Defender for Azure SQL alerts", + "description": "Microsoft Defender for Azure SQL ATP detects anomalous activities indicating unusual and potentially harmful attempts to access or exploit databases. Alerts can be configured and generated and will be reported in the Defender for console.", + "waf": "Security", + "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure" + }, + { + "category": "Defender", + "subcategory": "Vulnerability Assessment", + "text": "Configure Vulnerability Assessment (VA) findings and review recommendations", + "description": "Azure SQLDB vulnerability assessment is a service that provides visibility into your security state. Vulnerability assessment includes actionable steps to resolve security issues and enhance your database security. It can help you to monitor a dynamic database environment where changes are difficult to track and improve your SQL security posture.", + "waf": "Security", + "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview" + }, + { + "category": "Defender", + "subcategory": "Vulnerability Assessment", + "text": "Regularly review of Vulnerability Assessment (VA) findings and recommendations and prepare a plan to fix", + "description": "Microsoft Defender for Cloud provides vulnerability assessment for your Azure SQL Databases. Vulnerability assessment scans your databases for software vulnerabilities and provides a list of findings. You can use the findings to remediate software vulnerabilities and disable findings.", + "waf": "Security", + "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", + "severity": "High", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql" + }, + { + "category": "Encryption", + "subcategory": "Always Encrypted", + "text": "If protecting sensitive PII data from admin users is a key requirement, but Column Encryption limitations cannot be tolerated, consider the adoption of Always Encrypted with Secure Enclaves", + "description": "Always Encrypted with Secure Enclaves expands confidential computing capabilities of Always Encrypted by enabling in-place encryption and richer confidential queries. Always Encrypted with Secure Enclaves addresses these limitations by allowing some computations on plaintext data inside a secure enclave on the server side. Usage of this feature is recommended for the cases where you need to limit administrator access and need your queries to support more than equality matching of encrypted columns.", + "waf": "Security", + "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves" + }, + { + "category": "Encryption", + "subcategory": "Column Encryption", + "text": "To protect sensitive PII data from non-admin users in specific table columns, consider using Column Encryption", + "description": "With Azure SQL Database, you can apply symmetric encryption to a column of data by using Transact-SQL. This approach is called column encryption, because you can use it to encrypt specific columns with different encryption keys. Doing so gives you more granular encryption capability than TDE, which encrypts data in pages. Using Always Encrypted to ensure sensitive data isn't exposed in plaintext in Azure SQL Database or SQL Managed Instance, even in memory/in use. Always Encrypted protects the data from Database Administrators (DBAs) and cloud admins (or bad actors who can impersonate high-privileged but unauthorized users) and gives you more control over who can access your data.", + "waf": "Security", + "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption" + }, + { + "category": "Encryption", + "subcategory": "Transparent Data Encryption", + "text": "Ensure Transparent Data Encryption (TDE) is kept enabled", + "description": "Enabled by default, Transparent data encryption (TDE) helps to protect the database files against information disclosure by performing real-time encryption and decryption of the database, associated backups, and transaction log files 'at rest', without requiring changes to the application.", + "waf": "Security", + "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server" + }, + { + "category": "Encryption", + "subcategory": "Transparent Data Encryption", + "text": "Use customer-managed keys (CMK) in Azure Key Vault (AKV) if you need increased transparency and granular control over the TDE protection", + "description": "If separation of duties in the management of keys and data within the organization is required, leverage Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) for your Azure SQLDB and use Azure Key Vault to store (refer to its checklist). Leverage this feature when you have strict security requirements which cannot be met by the managed service keys.", + "waf": "Security", + "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview" + }, + { + "category": "Encryption", + "subcategory": "Transport Layer Security", + "text": "Enforce minimum TLS version to the latest available", + "description": "The minimal Transport Layer Security (TLS) version setting allows customers to choose which version of TLS their SQL database uses. It's possible to change the minimum TLS version by using the Azure portal, Azure PowerShell, and the Azure CLI.", + "waf": "Security", + "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version" + }, + { + "category": "Identity", + "subcategory": "Azure Active Directory", + "text": "Leverage Azure AD authentication for connections to Azure SQL Databases", + "description": "Use Azure Active Directory (Azure AD) authentication for centralized identity management. Use SQL Authentication only if really necessary and document as exceptions.", + "waf": "Security", + "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview" + }, + { + "category": "Identity", + "subcategory": "Azure Active Directory", + "text": "Create a separate Azure AD group with two admin accounts for each Azure SQL Database logical server", + "description": "Using Azure AD groups simplifies permission management and both the group owner, and the resource owner can add/remove members to/from the group. Create a separate group for Azure AD administrators for each logical server. Monitor Azure AD group membership changes using Azure AD audit activity reports.", + "waf": "Security", + "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities" + }, + { + "category": "Identity", + "subcategory": "Azure Active Directory", + "text": "Minimize the use of password-based authentication for applications", + "description": "Ensure that distinct system and user assigned managed identities, that are dedicated to the function, with least permissions assigned, are used for communication from Azure services and applications to the Azure SQLDB databases.", + "waf": "Security", + "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications" + }, + { + "category": "Identity", + "subcategory": "Managed Identities", + "text": "Assign Azure SQL Database a managed identity for outbound resource access", + "description": "System or User assigned managed identities enable Azure SQLDB to authenticate to other cloud services (e.g. Azure Key Vault) without storing credentials in code. Once enabled, all necessary permissions can be granted via Azure role-based-access-control to the specific Azure SQLDB instance. Do not share user assigned managed identities across multiple services if not strictly required.", + "waf": "Security", + "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview" + }, + { + "category": "Identity", + "subcategory": "Passwords", + "text": "Minimize the use of password-based authentication for users", + "description": "Use an Azure AD integrated authentication that eliminates the use of passwords. Password-based authentication methods are a weaker form of authentication. Credentials can be compromised or mistakenly given away. Use single sign-on authentication using Windows credentials. Federate the on-premises AD domain with Azure AD and use integrated Windows authentication (for domain-joined machines with Azure AD).", + "waf": "Security", + "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication" + }, + { + "category": "Ledger", + "subcategory": "Database Digest", + "text": "Use Azure Confidential Ledger to store database digests only if advanced security features are required", + "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Confidential Ledger is one of the supported store, it can be used and supports automatic generation and storage of database digests. Azure Ledger provides advanced security features like Blockchain Ledger Proof and Confidential Hardware Enclaves. Use it only if advanced security features are required, otherwise revert to Azure storage.", + "waf": "Security", + "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage" + }, + { + "category": "Ledger", + "subcategory": "Database Digest", + "text": "If Azure storage account is used to store database digests, ensure security is properly configured", + "description": "The hash of the latest block in the database ledger is called the database digest. It represents the state of all ledger tables in the database at the time when the block was generated. Generating a database digest is efficient, because it involves computing only the hashes of the blocks that were recently appended. Azure Blob Storage with Immutable Storage feature can be used and supports automatic generation and storage of database digests. To prevent tampering of your digest files, configure and lock a retention policy for your container.", + "waf": "Security", + "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management" + }, + { + "category": "Ledger", + "subcategory": "Integrity", + "text": "Schedule the Ledger verification process regularly to verify data integrity", + "description": "Ledger provides a form of data integrity called forward integrity, which provides evidence of data tampering on data in your ledger tables. The database verification process takes as input one or more previously generated database digests. It then recomputes the hashes stored in the database ledger based on the current state of the ledger tables. If the computed hashes don't match the input digests, the verification fails. The failure indicates that the data has been tampered with. The verification process reports all inconsistencies that it detects.", + "waf": "Security", + "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification" + }, + { + "category": "Ledger", + "subcategory": "Ledger", + "text": "If cryptographic proof of data integrity is a critical requirement, Ledger feature should be considered", + "description": "The Ledger feature provides tamper-evidence capabilities in your database. You can cryptographically attest to other parties, such as auditors or other business parties, that your data hasn't been tampered with. Ledger helps protect data from any attacker or high-privileged user, including database administrators (DBAs), system administrators, and cloud administrators.", + "waf": "Security", + "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview" + }, + { + "category": "Ledger", + "subcategory": "Recovery", + "text": "Prepare a response plan to investigate and repair a database after a tampering event", + "description": "Depending on the type of tampering, there are cases where you can repair the ledger without losing data. In the article contained in the --More Info-- column, different scenarios and recovery techniques are described.", + "waf": "Security", + "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering" + }, + { + "category": "Logging", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing is enabled at the server level", + "description": "Azure SQL Database Auditing tracks database events and writes them to an audit log in your Azure storage account. Auditing helps you understand database activity and gain insight into discrepancies and anomalies that could indicate business concerns or suspected security violations as well as helps you meet regulatory compliance. By default auditing policy includes all actions (queries, stored procedures and successful and failed logins) against the databases, which may result in high volume of audit logs. It's recommended for customers to configure auditing for different types of actions and action groups using PowerShell.", + "waf": "Security", + "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview" + }, + { + "category": "Logging", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Auditing logs are backed up and secured in the selected repository type", + "description": "Azure SQL Database Auditing logs can be written to external storage accounts, Log Analytics workspace or Event Hub. Be sure to protect the target repository using backups and secured configuration. Use Azure SQL Database Managed Identity to access the storage and set an explicit retention period. Do not grant permissions to administrators to the audit log repository. Use a different target storage for --Enabling Auditing of Microsoft support operations--. ", + "waf": "Security", + "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview" + }, + { + "category": "Logging", + "subcategory": "Auditing", + "text": "Ensure that Azure SQL Database Activity Log is collected and integrated with Auditing logs", + "description": "The Azure Monitor activity log is a platform log in Azure that provides insight into subscription-level events. The activity log includes information like when a resource is modified. It is recommended to send this activity log to the same external storage repository as the Azure SQL Database Audit Log (storage account, Log Analytics workspace, Event Hub).", + "waf": "Security", + "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log" + }, + { + "category": "Logging", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Auditing logs are being presented in to your organizations SIEM/SOAR", + "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR). Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", + "waf": "Security", + "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview" + }, + { + "category": "Logging", + "subcategory": "SIEM/SOAR", + "text": "Ensure that Azure SQL Database Activity Log data is presented in to your SIEM/SOAR", + "description": "Forward any logs from Azure SQL to your Security Information and Event Management (SIEM) and Security Orchestration Automation and Response (SOAR), which can be used to set up custom threat detections. Ensure that you are monitoring different types of Azure assets for potential threats and anomalies. Focus on getting high-quality alerts to reduce false positives for analysts to sort through. Alerts can be sourced from log data, agents, or other data.", + "waf": "Security", + "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log" + }, + { + "category": "Logging", + "subcategory": "SIEM/SOAR", + "text": "Ensure that you have response plans for malicious or aberrant audit logging events", + "description": "Security Operation Center (SOC) team should create an incident response plan (playbooks or manual responses) to investigate and mitigate tampering, malicious activities, and other anomalous behaviors.", + "waf": "Security", + "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log" + }, + { + "category": "Networking", + "subcategory": "Connectivity", + "text": "Review Public vs. Private Access connectivity methods and select the appropriate one for the workload", + "description": "When you create a logical server from the Azure portal for Azure SQL Database, the result is a public endpoint that is visible and reachable over the public network (Public Access). You can then limit connectivity based on firewall rules and Service Endpoint. You can also configure private connectivity only limiting connections to internal networks using Private Endpoint (Private Access). Private Access using Private Endpoint should be the default unless a business case or performance/technical reason applies that cannot support it. Usage of Private Endpoints has performance implications that need to be considered and assessed.", + "waf": "Security", + "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview" + }, + { + "category": "Networking", + "subcategory": "Connectivity", + "text": "Keep default Azure SQL Database Connection Policy if not differently required and justified", + "description": "IMPORTANT: Connections to private endpoint only support Proxy as the connection policy. When using private endpoints connections are proxied via the Azure SQL Database gateway to the database nodes. Clients will not have a direct connection.", + "waf": "Security", + "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture" + }, + { + "category": "Networking", + "subcategory": "Connectivity", + "text": "Ensure Allow Azure Services and Resources to Access this Server setting is disabled in Azure SQL Database firewall", + "description": "This option configures the firewall to allow all connections from Azure, including connections from the subscriptions of other customers. If you select this option, make sure that your login and user permissions limit access to authorized users only. If not strictly required, keep this setting to OFF.", + "waf": "Security", + "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview" + }, + { + "category": "Networking", + "subcategory": "Outbound Control", + "text": "Block or restrict outbound REST API calls to external endpoints", + "description": "Azure SQL Database has a new built-in feature that allows native integration with external REST endpoints. This means that integration of Azure SQL Database with Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management and in general any REST or even GraphQL endpoint. If not properly restricted, code inside an Azure SQL Database database could leverage this mechanism to exfiltrate data. If not strictly required, it is recommended to block or restrict this feature using Outbound Firewall Rules.", + "waf": "Security", + "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql" + }, + { + "category": "Networking", + "subcategory": "Outbound Control", + "text": "If outbound network access is required, it is recommended to configure outbound networking restrictions using built-in Azure SQL Database control feature", + "description": "Outbound firewall rules limit network traffic from the Azure SQL Database logical server to a customer defined list of Azure Storage accounts and Azure SQL Database logical servers. Any attempt to access storage accounts or databases not in this list is denied.", + "waf": "Security", + "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview" + }, + { + "category": "Networking", + "subcategory": "Private Access", + "text": "If Private Access connectivity is used, ensure that you are using the Private Endpoint, Azure Virtual Network, Azure Firewall, and Azure Network Security Group checklists", + "description": "Private Endpoint is created inside a subnet in an Azure Virtual Network. Proper security configuration must be applied also to the containing network environment, including NSG/ASG, UDR, firewall, monitoring and auditing.", + "waf": "Security", + "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server" + }, + { + "category": "Networking", + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, consider disabling Public Access connectivity", + "description": "When adding a Private Endpoint connection, public routing to your logical server isn't blocked by default. In the --Firewall and virtual networks-- pane, the setting --Deny public network access-- is not selected by default. To disable public network access, ensure that you select --Deny public network access--.", + "waf": "Security", + "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server" + }, + { + "category": "Networking", + "subcategory": "Private Access", + "text": "If Private Endpoint (Private Access) is used, apply NSG and eventually ASG to limit incoming source IP address ranges", + "description": "Network Security Group (NSG) and Application Security Group (ASG) can be now applied to subnet containing Private Endpoints to restrict connections to Azure SQLDB based on internal source IP ranges.", + "waf": "Security", + "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints" + }, + { + "category": "Networking", + "subcategory": "Private Access", + "text": "Apply Network Security Groups (NSG) and firewall rules to restrict access to Azure SQL Managed Instance internal subnet", + "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. Applications and tools that are in the same or peered virtual network in the same region could access it directly. Applications and tools that are in different region could use virtual-network-to-virtual-network connection or ExpressRoute circuit peering to establish connection. Customer should use Network Security Groups (NSG), and eventually internal firewalls, to restrict access over port 1433 only to resources that require access to a managed instance.", + "waf": "Security", + "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview" + }, + { + "category": "Networking", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, leverage Service Endpoint to restrict access from selected Azure Virtual Networks", + "description": "Azure Virtual Network Service Endpoint is preferred solution if you want to establish a direct connection to the Azure SQL Database backend nodes using Redirect policy. This will allow access in high performance mode and is the recommended approach from a performance perspective.", + "waf": "Security", + "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules" + }, + { + "category": "Networking", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used, ensure that only specific known IPs are added to the firewall", + "description": "The Azure SQL Database firewall allows you to specify IP address ranges from which communications are accepted. This approach is fine for stable IP addresses that are outside the Azure private network.", + "waf": "Security", + "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview" + }, + { + "category": "Networking", + "subcategory": "Public Access", + "text": "If Public Access connectivity is used and controlled by Azure SQL Database firewall rules, use database-level over server-level IP rules", + "description": "We recommend that you use database-level IP firewall rules whenever possible. This practice enhances security and makes your database more portable. Use server-level IP firewall rules for administrators. Also use them when you have many databases that have the same access requirements, and you don't want to configure each database individually.", + "waf": "Security", + "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure" + }, + { + "category": "Networking", + "subcategory": "Public Access", + "text": "Do not enable Azure SQL Managed Instance public endpoint", + "description": "A Managed Instance (SQL MI) can be isolated inside a virtual network to prevent external access. The Managed Instance public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. If company policy disallows the use of public endpoints, use Azure Policy to prevent enabling public endpoints in the first place.", + "waf": "Security", + "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview" + }, + { + "category": "Networking", + "subcategory": "Public Access", + "text": "Restrict access if Azure SQL Managed Instance public endpoint is required", + "description": "A Managed Instance (SQL MI) public endpoint is not enabled by default, must be explicitly enabled, only if strictly required. In this case, it is recommended to apply a Network Security Groups (NSG) to restrict access to port 3342 only to trusted source IP addresses.", + "waf": "Security", + "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", + "severity": "High", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview" + }, + { + "category": "Privileged Access", + "subcategory": "Lockbox", + "text": "Review and enable Customer Lockbox for Azure SQL Database access by Microsoft personnel", + "description": "Most operations, support, and troubleshooting performed by Microsoft personnel and sub-processors do not require access to customer data. In those rare circumstances where such access is required, Customer Lockbox for Microsoft Azure provides an interface for customers to review and approve or reject customer data access requests. In support scenarios where Microsoft needs to access customer data, Azure SQL Database supports Customer Lockbox to provide an interface for you to review and approve or reject customer data access requests.", + "waf": "Security", + "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", + "severity": "Low", + "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview" + }, + { + "category": "Privileged Access", + "subcategory": "Permissions", + "text": "Ensure that users are assigned the minimum level of access necessarily to complete their job functions", + "description": "The principle of least privilege states that users shouldn't have more privileges than needed to complete their tasks. High-privileged database and server users can perform many configuration and maintenance activities on the database and can also drop databases in Azure SQL instance. Tracking database owners and privileged accounts is important to avoid having excessive permission.", + "waf": "Security", + "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege" + }, + { + "category": "Privileged Access", + "subcategory": "Permissions", + "text": "Ensure that distinct applications will be assigned different credentials with minimal permissions to access Azure SQL Database", + "description": "Identities (both Users and SPNs) should be scoped to the least amount of access needed to perform the function. A higher number of tightly scoped SPNs should be used, instead of having one SPN with multiple sets of unrelated permissions. For example, if there are three external web applications hosted on-prem that make queries to the Azure SQL Database, they should not all use the same SPN for these activities. Instead, they should each have their own tightly scoped SPN.", + "waf": "Security", + "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", + "severity": "Low", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access" + } + ], + "categories": [ + { + "name": "BCDR" + }, + { + "name": "Defender" + }, + { + "name": "Encryption" + }, + { + "name": "Identity" + }, + { + "name": "Privileged Access" + }, + { + "name": "Ledger" + }, + { + "name": "Logging" + }, + { + "name": "Networking" + }, + { + "name": "Data Discovery and Classification" + }, + { + "name": "Data Masking" + }, + { + "name": "Code" + } + ], + "waf": [ + { + "name": "Reliability" + }, + { + "name": "Security" + }, + { + "name": "Cost" + }, + { + "name": "Operations" + }, + { + "name": "Performance" + } + ], + "yesno": [ + { + "name": "Yes" + }, + { + "name": "No" + } + ], + "status": [ + { + "name": "Not verified", + "description": "This check has not been looked at yet" + }, + { + "name": "Open", + "description": "There is an action item associated to this check" + }, + { + "name": "Fulfilled", + "description": "This check has been verified, and there are no further action items associated to it" + }, + { + "name": "Not required", + "description": "Recommendation understood, but not needed by current requirements" + }, + { + "name": "N/A", + "description": "Not applicable for current design" + } + ], + "severities": [ + { + "name": "High" + }, + { + "name": "Medium" + }, + { + "name": "Low" + } + ], + "metadata": { + "name": "Azure SQLDB Security Checklist (Preview)", + "state": "Preview", + "timestamp": "October 23, 2024" } - ], - "categories": [ - { - "name": "BCDR" - }, - { - "name": "Defender" - }, - { - "name": "Encryption" - }, - { - "name": "Identity" - }, - { - "name": "Privileged Access" - }, - { - "name": "Ledger" - }, - { - "name": "Logging" - }, - { - "name": "Networking" - }, - { - "name": "Data Discovery and Classification" - }, - { - "name": "Data Masking" - }, - { - "name": "Code" - } - ], - "waf": [ - { - "name": "Reliability" - }, - { - "name": "Security" - }, - { - "name": "Cost" - }, - { - "name": "Operations" - }, - { - "name": "Performance" - } - ], - "yesno": [ - { - "name": "Yes" - }, - { - "name": "No" - } - ], - "status": [ - { - "name": "Not verified", - "description": "This check has not been looked at yet" - }, - { - "name": "Open", - "description": "There is an action item associated to this check" - }, - { - "name": "Fulfilled", - "description": "This check has been verified, and there are no further action items associated to it" - }, - { - "name": "Not required", - "description": "Recommendation understood, but not needed by current requirements" - }, - { - "name": "N/A", - "description": "Not applicable for current design" - } - ], - "severities": [ - { - "name": "High" - }, - { - "name": "Medium" - }, - { - "name": "Low" - } - ], - "metadata": { - "name": "Azure SQLDB Security Checklist (Preview)", - "state": "Preview", - "timestamp": "10/20/2023 11:32:31" - } -} +} \ No newline at end of file diff --git a/checklists/sqldb_checklist.es.json b/checklists/sqldb_checklist.es.json index 13b88ca7..92680372 100644 --- a/checklists/sqldb_checklist.es.json +++ b/checklists/sqldb_checklist.es.json @@ -1,8 +1,7 @@ { - "$schema": "checklist.schema.json", "categories": [ { - "name": "BCDR" + "name": "BCDR (en inglés)" }, { "name": "Defensor" @@ -26,7 +25,7 @@ "name": "Gestión de redes" }, { - "name": "Descubrimiento y clasificación de datos" + "name": "Detección y clasificación de datos" }, { "name": "Enmascaramiento de datos" @@ -37,449 +36,549 @@ ], "items": [ { - "category": "BCDR", - "description": "Asegúrese de que sus copias de seguridad estén protegidas contra ataques. Esto debe incluir el cifrado de las copias de seguridad para proteger contra la pérdida de confidencialidad. Para la copia de seguridad regular del servicio de Azure, los datos de copia de seguridad se cifran automáticamente con claves administradas por la plataforma Azure. También puede optar por cifrar la copia de seguridad mediante una clave administrada por el cliente. En este caso, asegúrese de que esta clave administrada por el cliente en el almacén de claves también esté en el ámbito de copia de seguridad.", + "category": "BCDR (en inglés)", + "description": "Asegúrese de que sus copias de seguridad estén protegidas contra ataques. Esto debe incluir el cifrado de las copias de seguridad para protegerlas contra la pérdida de confidencialidad. Para la copia de seguridad periódica del servicio de Azure, los datos de copia de seguridad se cifran automáticamente mediante claves administradas por la plataforma Azure. También puede optar por cifrar la copia de seguridad mediante una clave administrada por el cliente. En este caso, asegúrese de que esta clave administrada por el cliente en el almacén de claves también esté en el ámbito de copia de seguridad.", "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", "severity": "Medio", "subcategory": "Azure Key Vault", - "text": "Proteja sus datos de copia de seguridad con cifrado y almacene claves de forma segura en Azure Key Vault" + "text": "Proteja los datos de copia de seguridad con cifrado y almacene las claves de forma segura en Azure Key Vault", + "waf": "Seguridad" }, { - "category": "BCDR", - "description": "Base de datos SQL de Azure usa la tecnología de SQL Server para crear copias de seguridad completas cada semana, copias de seguridad diferenciales cada 12 a 24 horas y copias de seguridad del registro de transacciones cada 5 a 10 minutos. De forma predeterminada, Base de datos SQL almacena datos en blobs de almacenamiento con redundancia geográfica que se replican en una región emparejada.", + "category": "BCDR (en inglés)", + "description": "Azure SQL Database usa la tecnología de SQL Server para crear copias de seguridad completas cada semana, copias de seguridad diferenciales cada 12-24 horas y copias de seguridad del registro de transacciones cada 5 a 10 minutos. De forma predeterminada, SQL Database almacena datos en blobs de almacenamiento con redundancia geográfica que se replican en una región emparejada.", "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", "severity": "Medio", "subcategory": "Copia de seguridad", - "text": "Configuración de copias de seguridad automatizadas de Base de datos SQL de Azure" + "text": "Configuración de copias de seguridad automatizadas de Azure SQL Database", + "waf": "Seguridad" }, { - "category": "BCDR", - "description": "De forma predeterminada, Base de datos SQL almacena datos en blobs de almacenamiento con redundancia geográfica que se replican en una región emparejada. Para Base de datos SQL, la redundancia de almacenamiento de copia de seguridad se puede configurar en el momento de la creación de la base de datos o se puede actualizar para una base de datos existente; Los cambios realizados en una base de datos existente solo se aplican a futuras copias de seguridad.", + "category": "BCDR (en inglés)", + "description": "De forma predeterminada, SQL Database almacena datos en blobs de almacenamiento con redundancia geográfica que se replican en una región emparejada. Para SQL Database, la redundancia de almacenamiento de copia de seguridad se puede configurar en el momento de la creación de la base de datos o se puede actualizar para una base de datos existente; Los cambios realizados en una base de datos existente solo se aplican a las copias de seguridad futuras.", "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", "severity": "Bajo", "subcategory": "Copia de seguridad", - "text": "Habilite el almacenamiento de copia de seguridad con redundancia geográfica para proteger contra fallas en una sola región y pérdida de datos" + "text": "Habilite el almacenamiento de copia de seguridad con redundancia geográfica para protegerse contra errores de una sola región y pérdida de datos", + "waf": "Seguridad" }, { "category": "Código", - "description": "El código malintencionado puede eludir potencialmente los controles de seguridad. Antes de implementar código personalizado en producción, es esencial revisar lo que se está implementando. Use una herramienta de base de datos como Azure Data Studio que admita el control de código fuente. Implementar herramientas y lógica para el análisis de código, vulnerabilidad y escaneo de credenciales.", + "description": "El código malicioso puede eludir los controles de seguridad. Antes de implementar código personalizado en producción, es esencial revisar lo que se está implementando. Use una herramienta de base de datos como Azure Data Studio que admita el control de código fuente. Implemente herramientas y lógica para el análisis de código, vulnerabilidades y escaneo de credenciales.", "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "Medio", "subcategory": "Control de código fuente y revisión de código", - "text": "Uso de sistemas de control de código fuente para almacenar, mantener y revisar el código de aplicación implementado en Azure SQLDB Database" + "text": "Use sistemas de control de código fuente para almacenar, mantener y revisar el código de la aplicación implementado en Azure SQLDB Database", + "waf": "Seguridad" }, { - "category": "Descubrimiento y clasificación de datos", - "description": "En caso de requisitos de clasificación, Purview es la opción preferida. Solo use SQL Data Discovery & Classification en caso de que Purview no sea una opción. Descubra columnas que potencialmente contengan datos confidenciales. Lo que se considera datos confidenciales depende en gran medida del cliente, la regulación de cumplimiento, etc., y debe ser evaluado por los usuarios a cargo de esos datos. Clasifique las columnas para usar escenarios avanzados de auditoría y protección basados en sensibilidad. Revise los resultados del descubrimiento automatizado y finalice la clasificación si es necesario.", + "category": "Detección y clasificación de datos", + "description": "En el caso de los requisitos de clasificación, Purview es la opción preferida. Utilice solo SQL Data Discovery & Classification en caso de que Purview no sea una opción. Detecte columnas que puedan contener datos confidenciales. Lo que se considera datos sensibles depende en gran medida del cliente, de la normativa de cumplimiento, etc., y debe ser evaluado por los usuarios a cargo de esos datos. Clasifique las columnas para usar escenarios avanzados de auditoría y protección basados en sensibilidad. Revise los resultados de la detección automatizada y finalice la clasificación si es necesario.", "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", "severity": "Bajo", - "subcategory": "Descubrimiento y clasificación de datos", - "text": "Planificar y configurar la clasificación y descubrimiento de datos para proteger los datos confidenciales" + "subcategory": "Detección y clasificación de datos", + "text": "Planifique y configure la detección y clasificación de datos para proteger los datos confidenciales", + "waf": "Seguridad" }, { "category": "Enmascaramiento de datos", - "description": "El uso de esta característica se recomienda solo si el cifrado de columnas no es una opción y existe un requisito específico para conservar los tipos y formatos de datos. El enmascaramiento dinámico de datos limita la exposición de datos confidenciales al enmascararlos a usuarios sin privilegios. El enmascaramiento dinámico de datos ayuda a evitar el acceso no autorizado a datos confidenciales al permitir a los clientes designar la cantidad de datos confidenciales que se revelarán con un impacto mínimo en la capa de aplicación.", + "description": "El uso de esta característica solo se recomienda si el cifrado de columnas no es una opción y hay un requisito específico para conservar los tipos y formatos de datos. El enmascaramiento dinámico de datos limita la exposición de datos confidenciales al enmascararlos a usuarios no privilegiados. El enmascaramiento dinámico de datos ayuda a evitar el acceso no autorizado a datos confidenciales al permitir que los clientes designen la cantidad de datos confidenciales que revelarán con un impacto mínimo en la capa de la aplicación.", "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", "severity": "Bajo", "subcategory": "Enmascaramiento de datos", - "text": "Utilice el enmascaramiento de datos para evitar el acceso no autorizado a los datos de usuarios no administradores si no es posible el cifrado" + "text": "Utilice el enmascaramiento de datos para evitar el acceso a los datos de usuarios no autorizados que no sean administradores si no es posible el cifrado", + "waf": "Seguridad" }, { "category": "Defensor", - "description": "SQL Advanced Threat Detection (ATP) proporciona una capa de seguridad que detecta posibles vulnerabilidades y actividad anómala en bases de datos, como ataques de inyección SQL y patrones de comportamiento inusuales. Cuando se detecta una amenaza potencial, Detección de amenazas envía una alerta procesable en tiempo real por correo electrónico y en Microsoft Defender para la nube, que incluye pasos claros de investigación y corrección para la amenaza específica.", + "description": "SQL Advanced Threat Detection (ATP) proporciona una capa de seguridad que detecta posibles vulnerabilidades y actividades anómalas en las bases de datos, como ataques de inyección SQL y patrones de comportamiento inusuales. Cuando se detecta una amenaza potencial, Detección de amenazas envía una alerta accionable en tiempo real por correo electrónico y en Microsoft Defender for Cloud, que incluye pasos claros de investigación y corrección para la amenaza específica.", "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "Alto", "subcategory": "Protección avanzada contra amenazas", - "text": "Revisar y completar la configuración de Advanced Threat Protection (ATP)" + "text": "Revisar y completar la configuración de Advanced Threat Protection (ATP)", + "waf": "Seguridad" }, { "category": "Defensor", - "description": "Habilite Microsoft Defender para Azure SQL en el nivel de suscripción para incorporar y proteger automáticamente todos los servidores y bases de datos existentes y futuros. Cuando se habilita en el nivel de suscripción, todas las bases de datos de Base de datos SQL de Azure y Instancia administrada de SQL de Azure están protegidas. A continuación, puede deshabilitarlos individualmente si lo desea. Si desea administrar manualmente qué bases de datos están protegidas, deshabilite en el nivel de suscripción y habilite cada base de datos que desee proteger.", + "description": "Habilite Microsoft Defender para Azure SQL en el nivel de suscripción para incorporar y proteger automáticamente todos los servidores y bases de datos existentes y futuros. Cuando se habilita en el nivel de suscripción, todas las bases de datos de Azure SQL Database y Azure SQL Managed Instance están protegidas. A continuación, puede desactivarlos individualmente si lo desea. Si desea administrar manualmente las bases de datos que están protegidas, deshabilite en el nivel de suscripción y habilite cada base de datos que desee proteger.", "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", "severity": "Alto", "subcategory": "Defender para Azure SQL", - "text": "Habilitar Microsoft Defender para Azure SQL" + "text": "Habilitación de Microsoft Defender para Azure SQL", + "waf": "Seguridad" }, { "category": "Defensor", - "description": "Microsoft Defender para Azure SQL ATP detecta actividades anómalas que indican intentos inusuales y potencialmente dañinos de acceso a bases de datos o aprovecharlas. Las alertas se pueden configurar y generar, y se informarán en el Defender para consola.", + "description": "Microsoft Defender para Azure SQL ATP detecta actividades anómalas que indican intentos inusuales y potencialmente dañinos de acceder a bases de datos o aprovecharlas. Las alertas se pueden configurar y generar, y se notificarán en Defender para consola.", "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "Alto", "subcategory": "Defender para Azure SQL", - "text": "Preparar un plan de respuesta de seguridad para reaccionar rápidamente a las alertas SQL de Microsoft Defender para Azure" + "text": "Prepare un plan de respuesta de seguridad para reaccionar rápidamente a las alertas de Microsoft Defender para Azure SQL", + "waf": "Seguridad" }, { "category": "Defensor", - "description": "La evaluación de vulnerabilidades de Azure SQLDB es un servicio que proporciona visibilidad del estado de seguridad. La evaluación de vulnerabilidades incluye pasos prácticos para resolver problemas de seguridad y mejorar la seguridad de la base de datos. Puede ayudarle a supervisar un entorno de base de datos dinámico donde los cambios son difíciles de rastrear y mejorar su postura de seguridad SQL.", + "description": "La evaluación de vulnerabilidades de Azure SQLDB es un servicio que proporciona visibilidad del estado de seguridad. La evaluación de vulnerabilidades incluye pasos prácticos para resolver problemas de seguridad y mejorar la seguridad de la base de datos. Puede ayudarle a supervisar un entorno de base de datos dinámico en el que los cambios son difíciles de rastrear y mejorar la posición de seguridad de SQL.", "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", "severity": "Alto", "subcategory": "Evaluación de vulnerabilidades", - "text": "Configurar los hallazgos de la evaluación de vulnerabilidades (VA) y revisar las recomendaciones" + "text": "Configurar los hallazgos de la evaluación de vulnerabilidades (VA) y revisar las recomendaciones", + "waf": "Seguridad" }, { "category": "Defensor", - "description": "Microsoft Defender para la nube proporciona una evaluación de vulnerabilidades para las bases de datos SQL de Azure. La evaluación de vulnerabilidades analiza las bases de datos en busca de vulnerabilidades de software y proporciona una lista de hallazgos. Puede usar los hallazgos para corregir vulnerabilidades de software y deshabilitar hallazgos.", + "description": "Microsoft Defender for Cloud proporciona una evaluación de vulnerabilidades para las bases de datos SQL de Azure. La evaluación de vulnerabilidades analiza las bases de datos en busca de vulnerabilidades de software y proporciona una lista de hallazgos. Puede utilizar los hallazgos para corregir vulnerabilidades de software y deshabilitar los hallazgos.", "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", "severity": "Alto", "subcategory": "Evaluación de vulnerabilidades", - "text": "Revisar regularmente los hallazgos y recomendaciones de la Evaluación de Vulnerabilidades (VA) y preparar un plan para corregir" + "text": "Revisar periódicamente los hallazgos y recomendaciones de la Evaluación de Vulnerabilidades (VA) y preparar un plan para solucionarlo.", + "waf": "Seguridad" }, { "category": "Encriptación", - "description": "Always Encrypted with Secure Enclaves amplía las capacidades informáticas confidenciales de Always Encrypted al permitir el cifrado in situ y consultas confidenciales más ricas. Always Encrypted with Secure Enclaves aborda estas limitaciones al permitir algunos cálculos en datos de texto sin formato dentro de un enclave seguro en el lado del servidor. Se recomienda el uso de esta función para los casos en los que necesite limitar el acceso de administrador y necesite que sus consultas admitan más que la coincidencia de igualdad de columnas cifradas.", + "description": "Always Encrypted with Secure Enclaves amplía las capacidades informáticas confidenciales de Always Encrypted al permitir el cifrado local y consultas confidenciales más completas. Always Encrypted with Secure Enclaves soluciona estas limitaciones al permitir algunos cálculos en datos de texto no cifrado dentro de un enclave seguro en el lado del servidor. Se recomienda el uso de esta característica para los casos en los que necesite limitar el acceso del administrador y necesite que sus consultas admitan algo más que la coincidencia de igualdad de columnas cifradas.", "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", "severity": "Medio", "subcategory": "Siempre encriptado", - "text": "Si proteger los datos PII confidenciales de los usuarios administradores es un requisito clave, pero no se pueden tolerar las limitaciones del cifrado de columnas, considere la adopción de Always Encrypted with Secure Enclaves" + "text": "Si la protección de los datos confidenciales de PII de los usuarios administradores es un requisito clave, pero no se pueden tolerar las limitaciones de Cifrado de columnas, considere la adopción de Siempre cifrado con enclaves seguros", + "waf": "Seguridad" }, { "category": "Encriptación", - "description": "Con Base de datos SQL de Azure, puede aplicar cifrado simétrico a una columna de datos mediante Transact-SQL. Este enfoque se denomina cifrado de columnas, ya que puede usarlo para cifrar columnas específicas con diferentes claves de cifrado. Hacerlo le brinda una capacidad de cifrado más granular que TDE, que cifra los datos en las páginas. Usar Always Encrypted para garantizar que los datos confidenciales no se expongan en texto sin formato en Base de datos SQL de Azure o Instancia administrada de SQL, incluso en memoria o en uso. Always Encrypted protege los datos de los administradores de bases de datos (DBA) y los administradores de la nube (o los malos actores que pueden hacerse pasar por usuarios con altos privilegios pero no autorizados) y le da más control sobre quién puede acceder a sus datos.", + "description": "Con Azure SQL Database, puede aplicar el cifrado simétrico a una columna de datos mediante Transact-SQL. Este enfoque se denomina cifrado de columnas, ya que se puede usar para cifrar columnas específicas con diferentes claves de cifrado. De este modo, se proporciona una capacidad de cifrado más granular que TDE, que cifra los datos de las páginas. Uso de Always Encrypted para asegurarse de que los datos confidenciales no se exponen en texto no cifrado en Azure SQL Database o SQL Managed Instance, incluso en memoria o en uso. Always Encrypted protege los datos de los administradores de bases de datos (DBA) y los administradores de la nube (o actores malintencionados que pueden hacerse pasar por usuarios no autorizados con muchos privilegios) y le proporciona más control sobre quién puede acceder a sus datos.", "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", "severity": "Bajo", "subcategory": "Cifrado de columnas", - "text": "Para proteger los datos confidenciales de PII de usuarios que no son administradores en columnas de tabla específicas, considere la posibilidad de usar el cifrado de columnas" + "text": "Para proteger los datos confidenciales de PII de usuarios que no son administradores en columnas de tabla específicas, considere la posibilidad de usar el cifrado de columnas", + "waf": "Seguridad" }, { "category": "Encriptación", - "description": "Habilitado de forma predeterminada, el cifrado de datos transparente (TDE) ayuda a proteger los archivos de base de datos contra la divulgación de información mediante el cifrado y descifrado en tiempo real de la base de datos, las copias de seguridad asociadas y los archivos de registro de transacciones \"en reposo\", sin necesidad de realizar cambios en la aplicación.", + "description": "Habilitado de forma predeterminada, el cifrado de datos transparente (TDE) ayuda a proteger los archivos de la base de datos contra la divulgación de información mediante la realización del cifrado y descifrado en tiempo real de la base de datos, las copias de seguridad asociadas y los archivos de registro de transacciones \"en reposo\", sin necesidad de realizar cambios en la aplicación.", "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "Alto", "subcategory": "Cifrado de datos transparente", - "text": "Asegúrese de que el cifrado de datos transparente (TDE) se mantenga habilitado" + "text": "Asegúrese de que el cifrado de datos transparente (TDE) se mantenga habilitado", + "waf": "Seguridad" }, { "category": "Encriptación", - "description": "Si se requiere la separación de tareas en la administración de claves y datos dentro de la organización, aproveche Customer Managed Keys (CMK) for Transparent Data Encryption (TDE) para su SQLDB de Azure y use Azure Key Vault para almacenar (consulte su lista de comprobación). Aproveche esta característica cuando tenga requisitos de seguridad estrictos que no puedan cumplir las claves de servicio administradas.", + "description": "Si se requiere la separación de funciones en la administración de claves y datos dentro de la organización, aproveche las claves administradas por el cliente (CMK) para el cifrado de datos transparente (TDE) para su Azure SQLDB y use Azure Key Vault para almacenar (consulte su lista de comprobación). Aproveche esta característica cuando tenga requisitos de seguridad estrictos que no puedan cumplir las claves de servicio administradas.", "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", "severity": "Medio", "subcategory": "Cifrado de datos transparente", - "text": "Use claves administradas por el cliente (CMK) en Azure Key Vault (AKV) si necesita mayor transparencia y control granular sobre la protección TDE" + "text": "Use claves administradas por el cliente (CMK) en Azure Key Vault (AKV) si necesita una mayor transparencia y control pormenorizado sobre la protección de TDE", + "waf": "Seguridad" }, { "category": "Encriptación", - "description": "La configuración de versión mínima de Seguridad de la capa de transporte (TLS) permite a los clientes elegir qué versión de TLS utiliza su base de datos SQL. Es posible cambiar la versión mínima de TLS mediante Azure Portal, Azure PowerShell y la CLI de Azure.", + "description": "La configuración de versión mínima de Seguridad de la capa de transporte (TLS) permite a los clientes elegir qué versión de TLS usa su base de datos SQL. Es posible cambiar la versión mínima de TLS mediante Azure Portal, Azure PowerShell y la CLI de Azure.", "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", "severity": "Alto", "subcategory": "Seguridad de la capa de transporte", - "text": "Aplicar la versión mínima de TLS a la última disponible" + "text": "Aplicar la versión mínima de TLS a la última disponible", + "waf": "Seguridad" }, { "category": "Identidad", - "description": "Use la autenticación de Azure Active Directory (Azure AD) para la administración centralizada de identidades. Utilice la autenticación de SQL solo si es realmente necesario y documente como excepciones.", + "description": "Use la autenticación de Azure Active Directory (Azure AD) para la administración centralizada de identidades. Utilice la autenticación SQL solo si es realmente necesario y documente como excepciones.", "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", "severity": "Medio", "subcategory": "Azure Active Directory", - "text": "Aprovechar la autenticación de Azure AD para las conexiones a Bases de datos SQL de Azure" + "text": "Aproveche la autenticación de Azure AD para las conexiones a Azure SQL Databases", + "waf": "Seguridad" }, { "category": "Identidad", - "description": "El uso de grupos de Azure AD simplifica la administración de permisos y tanto el propietario del grupo como el propietario del recurso pueden agregar o quitar miembros del grupo. Cree un grupo independiente para los administradores de Azure AD para cada servidor lógico. Supervise los cambios de pertenencia a grupos de Azure AD mediante los informes de actividad de auditoría de Azure AD.", + "description": "El uso de grupos de Azure AD simplifica la administración de permisos y tanto el propietario del grupo como el propietario del recurso pueden agregar o quitar miembros del grupo. Cree un grupo independiente para los administradores de Azure AD para cada servidor lógico. Supervise los cambios en la pertenencia a grupos de Azure AD mediante los informes de actividad de auditoría de Azure AD.", "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", "severity": "Medio", "subcategory": "Azure Active Directory", - "text": "Creación de un grupo de Azure AD independiente con dos cuentas de administrador para cada servidor lógico de Base de datos SQL de Azure" + "text": "Creación de un grupo de Azure AD independiente con dos cuentas de administrador para cada servidor lógico de Azure SQL Database", + "waf": "Seguridad" }, { "category": "Identidad", - "description": "Asegúrese de que se usan distintas identidades administradas asignadas por el sistema y el usuario, dedicadas a la función, con menos permisos asignados, para la comunicación entre los servicios y aplicaciones de Azure a las bases de datos SQLDB de Azure.", + "description": "Asegúrese de que las identidades administradas asignadas por el sistema y el usuario distintas, dedicadas a la función, con el mínimo de permisos asignados, se usen para la comunicación entre los servicios y las aplicaciones de Azure y las bases de datos de Azure SQLDB.", "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", "severity": "Medio", "subcategory": "Azure Active Directory", - "text": "Minimice el uso de la autenticación basada en contraseña para las aplicaciones" + "text": "Minimice el uso de la autenticación basada en contraseña para las aplicaciones", + "waf": "Seguridad" }, { "category": "Identidad", - "description": "Las identidades administradas asignadas por el sistema o el usuario permiten que Azure SQLDB se autentique en otros servicios en la nube (por ejemplo, Azure Key Vault) sin almacenar credenciales en el código. Una vez habilitado, se pueden conceder todos los permisos necesarios a través de Azure role-based-access-control a la instancia específica de Azure SQLDB. No comparta identidades administradas asignadas por el usuario en varios servicios si no es estrictamente necesario.", + "description": "Las identidades administradas asignadas por el sistema o por el usuario permiten que Azure SQLDB se autentique en otros servicios en la nube (por ejemplo, Azure Key Vault) sin almacenar credenciales en el código. Una vez habilitado, se pueden conceder todos los permisos necesarios a través del control de acceso basado en roles de Azure a la instancia específica de Azure SQLDB. No comparta identidades administradas asignadas por el usuario entre varios servicios si no es estrictamente necesario.", "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "severity": "Bajo", "subcategory": "Identidades administradas", - "text": "Asignación de una identidad administrada a Base de datos SQL de Azure para el acceso a recursos salientes" + "text": "Asignación de Azure SQL Database a una identidad administrada para el acceso a recursos de salida", + "waf": "Seguridad" }, { "category": "Identidad", - "description": "Use una autenticación integrada de Azure AD que elimine el uso de contraseñas. Los métodos de autenticación basados en contraseña son una forma más débil de autenticación. Las credenciales pueden verse comprometidas o regalarse por error. Use la autenticación de inicio de sesión único con credenciales de Windows. Federe el dominio de AD local con Azure AD y use la autenticación integrada de Windows (para máquinas unidas a un dominio con Azure AD).", + "description": "Use una autenticación integrada de Azure AD que elimine el uso de contraseñas. Los métodos de autenticación basados en contraseñas son una forma más débil de autenticación. Las credenciales pueden verse comprometidas o cedidas por error. Utilice la autenticación de inicio de sesión único con credenciales de Windows. Federe el dominio de AD local con Azure AD y use la autenticación integrada de Windows (para máquinas unidas a un dominio con Azure AD).", "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", "severity": "Medio", "subcategory": "Contraseñas", - "text": "Minimice el uso de la autenticación basada en contraseña para los usuarios" + "text": "Minimice el uso de la autenticación basada en contraseña para los usuarios", + "waf": "Seguridad" }, { "category": "Libro mayor", - "description": "El hash del último bloque en el libro mayor de la base de datos se denomina resumen de la base de datos. Representa el estado de todas las tablas de contabilidad de la base de datos en el momento en que se generó el bloque. Generar un resumen de base de datos es eficiente, ya que implica calcular solo los hashes de los bloques que se agregaron recientemente. Azure Confidential Ledger es uno de los almacenes compatibles, se puede usar y admite la generación y el almacenamiento automáticos de resúmenes de bases de datos. Azure Ledger proporciona características de seguridad avanzadas como Blockchain Ledger Proof y Confidential Hardware Enclaves. Úselo solo si se requieren características de seguridad avanzadas y, de lo contrario, vuelva al almacenamiento de Azure.", + "description": "El hash del último bloque en el libro mayor de la base de datos se denomina resumen de la base de datos. Representa el estado de todas las tablas del libro mayor de la base de datos en el momento en que se generó el bloque. La generación de un resumen de base de datos es eficiente, ya que implica calcular solo los hashes de los bloques que se agregaron recientemente. Azure Confidential Ledger es uno de los almacenes compatibles, se puede usar y admite la generación y el almacenamiento automáticos de resúmenes de bases de datos. Azure Ledger proporciona características de seguridad avanzadas, como Blockchain, Ledger, Proof y Confidential Hardware Enclaves. Úselo solo si se requieren características de seguridad avanzadas, de lo contrario, vuelva al almacenamiento de Azure.", "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", "severity": "Medio", "subcategory": "Resumen de base de datos", - "text": "Usar Azure Confidential Ledger para almacenar resúmenes de base de datos solo si se requieren características de seguridad avanzadas" + "text": "Use Azure Confidential Ledger para almacenar resúmenes de bases de datos solo si se requieren características de seguridad avanzadas", + "waf": "Seguridad" }, { "category": "Libro mayor", - "description": "El hash del último bloque en el libro mayor de la base de datos se denomina resumen de la base de datos. Representa el estado de todas las tablas de contabilidad de la base de datos en el momento en que se generó el bloque. Generar un resumen de base de datos es eficiente, ya que implica calcular solo los hashes de los bloques que se agregaron recientemente. La característica Azure Blob Storage with Immutable Storage se puede usar y admite la generación y el almacenamiento automáticos de resúmenes de bases de datos. Para evitar la manipulación de los archivos de resumen, configure y bloquee una directiva de retención para el contenedor.", + "description": "El hash del último bloque en el libro mayor de la base de datos se denomina resumen de la base de datos. Representa el estado de todas las tablas del libro mayor de la base de datos en el momento en que se generó el bloque. La generación de un resumen de base de datos es eficiente, ya que implica calcular solo los hashes de los bloques que se agregaron recientemente. Se puede usar la característica Azure Blob Storage con almacenamiento inmutable y admite la generación y el almacenamiento automáticos de resúmenes de bases de datos. Para evitar la manipulación de los archivos de resumen, configure y bloquee una directiva de retención para el contenedor.", "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", "severity": "Medio", "subcategory": "Resumen de base de datos", - "text": "Si se usa la cuenta de almacenamiento de Azure para almacenar resúmenes de base de datos, asegúrese de que la seguridad esté configurada correctamente" + "text": "Si se usa la cuenta de almacenamiento de Azure para almacenar resúmenes de base de datos, asegúrese de que la seguridad esté configurada correctamente", + "waf": "Seguridad" }, { "category": "Libro mayor", - "description": "El libro mayor proporciona una forma de integridad de datos denominada integridad hacia adelante, que proporciona evidencia de manipulación de datos en los datos de las tablas del libro mayor. El proceso de verificación de la base de datos toma como entrada uno o más resúmenes de base de datos generados previamente. A continuación, vuelve a calcular los hashes almacenados en el libro mayor de la base de datos en función del estado actual de las tablas del libro mayor. Si los hashes calculados no coinciden con los resúmenes de entrada, se produce un error en la verificación. El error indica que los datos han sido manipulados. El proceso de verificación informa de todas las inconsistencias que detecta.", + "description": "Ledger proporciona una forma de integridad de datos llamada integridad directa, que proporciona pruebas de la manipulación de datos en los datos de tus tablas de ledger. El proceso de verificación de la base de datos toma como entrada uno o más resúmenes de base de datos generados previamente. A continuación, vuelve a calcular los hashes almacenados en el libro mayor de la base de datos en función del estado actual de las tablas del libro mayor. Si los hashes calculados no coinciden con los resúmenes de entrada, se produce un error en la comprobación. El error indica que los datos han sido manipulados. El proceso de verificación informa de todas las inconsistencias que detecta.", "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", "severity": "Medio", "subcategory": "Integridad", - "text": "Programe el proceso de verificación del libro mayor regularmente para verificar la integridad de los datos" + "text": "Programe el proceso de verificación de Ledger con regularidad para verificar la integridad de los datos", + "waf": "Seguridad" }, { "category": "Libro mayor", - "description": "La función Ledger proporciona capacidades de evidencia de manipulación en su base de datos. Puede dar fe criptográficamente a otras partes, como auditores u otras partes comerciales, de que sus datos no han sido manipulados. Ledger ayuda a proteger los datos de cualquier atacante o usuario con privilegios altos, incluidos los administradores de bases de datos (DBA), los administradores de sistemas y los administradores de la nube.", + "description": "La función Ledger proporciona capacidades de evidencia de manipulación en su base de datos. Puede dar fe criptográficamente a otras partes, como auditores u otras partes comerciales, de que sus datos no han sido manipulados. Ledger ayuda a proteger los datos de cualquier atacante o usuario con muchos privilegios, incluidos los administradores de bases de datos (DBA), los administradores de sistemas y los administradores de la nube.", "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", "severity": "Medio", "subcategory": "Libro mayor", - "text": "Si la prueba criptográfica de la integridad de los datos es un requisito crítico, se debe considerar la función Ledger" + "text": "Si la prueba criptográfica de la integridad de los datos es un requisito crítico, se debe considerar la función Ledger", + "waf": "Seguridad" }, { "category": "Libro mayor", - "description": "Dependiendo del tipo de manipulación, hay casos en los que puede reparar el libro mayor sin perder datos. En el artículo contenido en la columna --Más información-- se describen diferentes escenarios y técnicas de recuperación.", + "description": "Dependiendo del tipo de manipulación, hay casos en los que se puede reparar el libro mayor sin perder datos. En el artículo contenido en la columna --Más Info-- se describen diferentes escenarios y técnicas de recuperación.", "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", "severity": "Medio", "subcategory": "Recuperación", - "text": "Preparar un plan de respuesta para investigar y reparar una base de datos después de un evento de manipulación" + "text": "Preparar un plan de respuesta para investigar y reparar una base de datos después de un evento de manipulación", + "waf": "Seguridad" }, { "category": "Registro", - "description": "Azure SQL Database Auditing realiza un seguimiento de los eventos de la base de datos y los escribe en un registro de auditoría de la cuenta de almacenamiento de Azure. La auditoría le ayuda a comprender la actividad de la base de datos y a obtener información sobre discrepancias y anomalías que podrían indicar problemas empresariales o sospechas de infracciones de seguridad, así como a cumplir las normativas. De forma predeterminada, la directiva de auditoría incluye todas las acciones (consultas, procedimientos almacenados e inicios de sesión correctos y erróneos) en las bases de datos, lo que puede dar lugar a un gran volumen de registros de auditoría. Se recomienda que los clientes configuren la auditoría para diferentes tipos de acciones y grupos de acciones mediante PowerShell.", + "description": "Auditoría de Azure SQL Database realiza un seguimiento de los eventos de la base de datos y los escribe en un registro de auditoría de la cuenta de almacenamiento de Azure. La auditoría le ayuda a comprender la actividad de la base de datos y a obtener información sobre las discrepancias y anomalías que podrían indicar problemas empresariales o presuntas violaciones de seguridad, así como a cumplir con la normativa. De forma predeterminada, la directiva de auditoría incluye todas las acciones (consultas, procedimientos almacenados e inicios de sesión correctos y erróneos) en las bases de datos, lo que puede dar lugar a un gran volumen de registros de auditoría. Se recomienda que los clientes configuren la auditoría para diferentes tipos de acciones y grupos de acciones mediante PowerShell.", "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "Medio", "subcategory": "Auditoría", - "text": "Asegúrese de que Azure SQL Database Auditing está habilitado en el nivel de servidor" + "text": "Asegúrese de que la auditoría de Azure SQL Database está habilitada en el nivel de servidor", + "waf": "Seguridad" }, { "category": "Registro", - "description": "Los registros de auditoría de Base de datos SQL de Azure se pueden escribir en cuentas de almacenamiento externo, en el área de trabajo de Log Analytics o en el Centro de eventos. Asegúrese de proteger el repositorio de destino mediante copias de seguridad y configuración segura. Use Azure SQL Database Managed Identity para acceder al almacenamiento y establecer un período de retención explícito. No conceda permisos a los administradores para el repositorio del registro de auditoría. Utilice un almacenamiento de destino diferente para --Habilitación de la auditoría de las operaciones de soporte técnico de Microsoft--. ", + "description": "Los registros de auditoría de Azure SQL Database se pueden escribir en cuentas de almacenamiento externas, áreas de trabajo de Log Analytics o Event Hub. Asegúrese de proteger el repositorio de destino mediante copias de seguridad y configuración segura. Use Azure SQL Database Managed Identity para acceder al almacenamiento y establecer un período de retención explícito. No conceda permisos a los administradores para el repositorio de registros de auditoría. Use un almacenamiento de destino diferente para habilitar la auditoría de las operaciones de soporte técnico de Microsoft--. ", "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "Bajo", "subcategory": "Auditoría", - "text": "Asegúrese de que los registros de auditoría de Base de datos SQL de Azure están respaldados y protegidos en el tipo de repositorio seleccionado" + "text": "Asegúrese de que se realiza una copia de seguridad de los registros de auditoría de Azure SQL Database y se protegen en el tipo de repositorio seleccionado", + "waf": "Seguridad" }, { "category": "Registro", - "description": "El registro de actividad de Azure Monitor es un registro de plataforma en Azure que proporciona información sobre los eventos de nivel de suscripción. El registro de actividad incluye información como cuando se modifica un recurso. Se recomienda enviar este registro de actividad al mismo repositorio de almacenamiento externo que el registro de auditoría de Base de datos SQL de Azure (cuenta de almacenamiento, área de trabajo de Log Analytics, Centro de eventos).", + "description": "El registro de actividad de Azure Monitor es un registro de plataforma en Azure que proporciona información sobre los eventos de nivel de suscripción. El registro de actividad incluye información como cuándo se modifica un recurso. Se recomienda enviar este registro de actividad al mismo repositorio de almacenamiento externo que el registro de auditoría de Azure SQL Database (cuenta de almacenamiento, área de trabajo de Log Analytics, centro de eventos).", "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "Medio", "subcategory": "Auditoría", - "text": "Asegúrese de que el registro de actividad de Base de datos SQL de Azure se recopila e integra con los registros de auditoría" + "text": "Asegúrese de que el registro de actividad de Azure SQL Database se recopila e integra con los registros de auditoría", + "waf": "Seguridad" }, { "category": "Registro", - "description": "Reenvíe los registros de Azure SQL a su administración de eventos e información de seguridad (SIEM) y a Security Orchestration Automation and Response (SOAR). Asegúrese de que está supervisando diferentes tipos de activos de Azure para detectar posibles amenazas y anomalías. Concéntrese en obtener alertas de alta calidad para reducir los falsos positivos para que los analistas los clasifiquen. Las alertas pueden obtenerse de datos de registro, agentes u otros datos.", + "description": "Reenvíe los registros de Azure SQL a la administración de eventos e información de seguridad (SIEM) y a la automatización y respuesta de orquestación de seguridad (SOAR). Asegúrese de que está supervisando los diferentes tipos de recursos de Azure en busca de posibles amenazas y anomalías. Concéntrese en obtener alertas de alta calidad para reducir los falsos positivos que los analistas deben clasificar. Las alertas pueden provenir de datos de registro, agentes u otros datos.", "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "Medio", "subcategory": "SIEM/SOAR", - "text": "Asegúrese de que los registros de auditoría de Base de datos SQL de Azure se presentan en SIEM/SOAR de su organización" + "text": "Asegúrese de que los registros de auditoría de Azure SQL Database se presentan en SIEM/SOAR de su organización", + "waf": "Seguridad" }, { "category": "Registro", - "description": "Reenvíe los registros de Azure SQL a su Administración de eventos e información de seguridad (SIEM) y Automatización y respuesta de orquestación de seguridad (SOAR), que se pueden usar para configurar detecciones de amenazas personalizadas. Asegúrese de que está supervisando diferentes tipos de activos de Azure para detectar posibles amenazas y anomalías. Concéntrese en obtener alertas de alta calidad para reducir los falsos positivos para que los analistas los clasifiquen. Las alertas pueden obtenerse de datos de registro, agentes u otros datos.", + "description": "Reenvíe los registros de Azure SQL a la administración de eventos e información de seguridad (SIEM) y a la automatización y respuesta de orquestación de seguridad (SOAR), que se pueden usar para configurar detecciones de amenazas personalizadas. Asegúrese de que está supervisando los diferentes tipos de recursos de Azure en busca de posibles amenazas y anomalías. Concéntrese en obtener alertas de alta calidad para reducir los falsos positivos que los analistas deben clasificar. Las alertas pueden provenir de datos de registro, agentes u otros datos.", "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "Medio", "subcategory": "SIEM/SOAR", - "text": "Asegúrese de que los datos del registro de actividad de Base de datos SQL de Azure se presentan en su SIEM/SOAR" + "text": "Asegúrese de que los datos del registro de actividad de Azure SQL Database se presentan en su SIEM/SOAR", + "waf": "Seguridad" }, { "category": "Registro", - "description": "El equipo del Centro de Operaciones de Seguridad (SOC) debe crear un plan de respuesta a incidentes (cuadernos de jugadas o respuestas manuales) para investigar y mitigar la manipulación, las actividades maliciosas y otros comportamientos anómalos.", + "description": "El equipo del Centro de operaciones de seguridad (SOC) debe crear un plan de respuesta a incidentes (cuadernos de estrategias o respuestas manuales) para investigar y mitigar la manipulación, las actividades maliciosas y otros comportamientos anómalos.", "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "Medio", "subcategory": "SIEM/SOAR", - "text": "Asegúrese de que tiene planes de respuesta para eventos de registro de auditoría malintencionados o aberrantes" + "text": "Asegúrese de que tiene planes de respuesta para eventos de registro de auditoría malintencionados o aberrantes", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Al crear un servidor lógico desde Azure Portal para Base de datos SQL de Azure, el resultado es un punto de conexión público visible y accesible a través de la red pública (acceso público). A continuación, puede limitar la conectividad en función de las reglas de firewall y Service Endpoint. También puede configurar la conectividad privada limitando solo las conexiones a redes internas mediante Private Endpoint (Private Access). El acceso privado mediante un punto de conexión privado debe ser el valor predeterminado, a menos que se aplique un caso de negocio o una razón técnica o de rendimiento que no pueda admitirlo. El uso de puntos finales privados tiene implicaciones de rendimiento que deben tenerse en cuenta y evaluarse.", + "description": "Al crear un servidor lógico desde Azure Portal para Azure SQL Database, el resultado es un punto de conexión público visible y accesible a través de la red pública (acceso público). A continuación, puede limitar la conectividad en función de las reglas de firewall y el punto de conexión de servicio. También puede configurar solo la conectividad privada, limitando las conexiones a las redes internas mediante el punto de conexión privado (acceso privado). El acceso privado mediante un punto de conexión privado debe ser el valor predeterminado, a menos que se aplique un caso de negocio o un motivo técnico o de rendimiento que no lo admita. El uso de puntos de conexión privados tiene implicaciones de rendimiento que deben tenerse en cuenta y evaluarse.", "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "Alto", "subcategory": "Conectividad", - "text": "Revise los métodos de conectividad de acceso público frente al acceso privado y seleccione el adecuado para la carga de trabajo" + "text": "Revise los métodos de conectividad de acceso público frente a privado y seleccione el adecuado para la carga de trabajo", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "IMPORTANTE: Las conexiones a un punto de enlace privado solo admiten proxy como directiva de conexión. Cuando se usan puntos de conexión privados, las conexiones se envían mediante proxy a través de la puerta de enlace de Base de datos SQL de Azure a los nodos de la base de datos. Los clientes no tendrán una conexión directa.", + "description": "IMPORTANTE: Las conexiones a terminales privados solo admiten Proxy como política de conexión. Cuando se usan puntos de conexión privados, las conexiones se envían mediante proxy a través de la puerta de enlace de Azure SQL Database a los nodos de la base de datos. Los clientes no tendrán una conexión directa.", "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", "severity": "Bajo", "subcategory": "Conectividad", - "text": "Mantener la directiva de conexión predeterminada de Base de datos SQL de Azure si no se requiere y justifica de manera diferente" + "text": "Mantener la directiva de conexión predeterminada de Azure SQL Database si no se requiere y justifica de manera diferente", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Esta opción configura el firewall para permitir todas las conexiones de Azure, incluidas las conexiones de las suscripciones de otros clientes. Si selecciona esta opción, asegúrese de que sus permisos de inicio de sesión y de usuario limiten el acceso solo a usuarios autorizados. Si no es estrictamente necesario, mantenga esta configuración en OFF.", + "description": "Esta opción configura el firewall para permitir todas las conexiones de Azure, incluidas las conexiones de las suscripciones de otros clientes. Si selecciona esta opción, asegúrese de que sus permisos de inicio de sesión y de usuario limiten el acceso solo a los usuarios autorizados. Si no es estrictamente necesario, mantenga esta configuración en OFF.", "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "Alto", "subcategory": "Conectividad", - "text": "Asegúrese de que la opción Permitir que los servicios y recursos de Azure accedan a este servidor esté deshabilitada en el firewall de Base de datos SQL de Azure." + "text": "Asegúrese de que la opción Permitir que los servicios y recursos de Azure accedan a este servidor esté deshabilitada en el firewall de Azure SQL Database", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Base de datos SQL de Azure tiene una nueva característica integrada que permite la integración nativa con puntos de conexión REST externos. Esto significa que la integración de Azure SQL Database con Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management y, en general, cualquier punto de conexión REST o incluso GraphQL. Si no se restringe correctamente, el código dentro de una base de datos de Base de datos SQL de Azure podría aprovechar este mecanismo para filtrar datos. Si no es estrictamente necesario, se recomienda bloquear o restringir esta función mediante las reglas de firewall saliente.", + "description": "Azure SQL Database tiene una nueva característica integrada que permite la integración nativa con puntos de conexión REST externos. Esto significa que la integración de Azure SQL Database con Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management y, en general, cualquier punto de conexión REST o incluso GraphQL. Si no se restringe correctamente, el código dentro de una base de datos de Azure SQL Database podría aprovechar este mecanismo para filtrar datos. Si no es estrictamente necesario, se recomienda bloquear o restringir esta función mediante las reglas de firewall de salida.", "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", "severity": "Medio", "subcategory": "Control de salida", - "text": "Bloquear o restringir las llamadas salientes a la API de REST a puntos de conexión externos" + "text": "Bloquear o restringir las llamadas salientes a la API de REST a puntos de conexión externos", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Las reglas de firewall saliente limitan el tráfico de red desde el servidor lógico de Base de datos SQL de Azure a una lista definida por el cliente de cuentas de almacenamiento de Azure y servidores lógicos de Base de datos SQL de Azure. Se deniega cualquier intento de obtener acceso a cuentas de almacenamiento o bases de datos que no estén en esta lista.", + "description": "Las reglas de firewall de salida limitan el tráfico de red desde el servidor lógico de Azure SQL Database a una lista definida por el cliente de cuentas de Azure Storage y servidores lógicos de Azure SQL Database. Se deniega cualquier intento de acceder a cuentas de almacenamiento o bases de datos que no estén en esta lista.", "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", "severity": "Medio", "subcategory": "Control de salida", - "text": "Si se requiere acceso a la red saliente, se recomienda configurar las restricciones de red salientes mediante la característica de control integrada Base de datos SQL de Azure." + "text": "Si se requiere acceso a la red de salida, se recomienda configurar las restricciones de red de salida mediante la característica de control integrada de Azure SQL Database", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Private Endpoint se crea dentro de una subred en una red virtual de Azure. La configuración de seguridad adecuada debe aplicarse también al entorno de red que lo contiene, incluidos NSG / ASG, UDR, firewall, monitoreo y auditoría.", + "description": "El punto de conexión privado se crea dentro de una subred en una red virtual de Azure. La configuración de seguridad adecuada también debe aplicarse al entorno de red contenedor, incluidos NSG/ASG, UDR, firewall, monitoreo y auditoría.", "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "Medio", "subcategory": "Acceso privado", - "text": "Si se usa la conectividad de acceso privado, asegúrese de que está usando las listas de comprobación Punto de conexión privado, Red virtual de Azure, Firewall de Azure y Grupo de seguridad de red de Azure." + "text": "Si se usa la conectividad de Private Access, asegúrese de que está usando las listas de comprobación Punto de conexión privado, Red virtual de Azure, Azure Firewall y Grupo de seguridad de red de Azure", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Al agregar una conexión de extremo privado, el enrutamiento público al servidor lógico no se bloquea de forma predeterminada. En el panel --Firewall y redes virtuales-- , la configuración --Denegar acceso a la red pública-- no está seleccionada de forma predeterminada. Para deshabilitar el acceso a la red pública, asegúrese de seleccionar --Denegar acceso a la red pública--.", + "description": "Al agregar una conexión de punto de conexión privado, el enrutamiento público al servidor lógico no se bloquea de forma predeterminada. En el panel --Firewall y redes virtuales-, la opción --Denegar acceso a la red pública-- no está seleccionada de forma predeterminada. Para deshabilitar el acceso a la red pública, asegúrese de seleccionar --Denegar el acceso a la red pública--.", "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "Alto", "subcategory": "Acceso privado", - "text": "Si se usa el extremo privado (acceso privado), considere la posibilidad de deshabilitar la conectividad de acceso público" + "text": "Si se usa el punto de conexión privado (acceso privado), considere la posibilidad de deshabilitar la conectividad de acceso público", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "El grupo de seguridad de red (NSG) y el grupo de seguridad de aplicaciones (ASG) ahora se pueden aplicar a subredes que contienen puntos de conexión privados para restringir las conexiones a Azure SQLDB en función de intervalos IP de origen internos.", + "description": "El grupo de seguridad de red (NSG) y el grupo de seguridad de aplicaciones (ASG) ahora se pueden aplicar a la subred que contiene puntos de conexión privados para restringir las conexiones a Azure SQLDB en función de los intervalos IP de origen internos.", "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", "severity": "Medio", "subcategory": "Acceso privado", - "text": "Si se usa Private Endpoint (Private Access), aplique NSG y, finalmente, ASG para limitar los intervalos de direcciones IP de origen entrantes" + "text": "Si se usa el punto de conexión privado (acceso privado), aplique NSG y, finalmente, ASG para limitar los intervalos de direcciones IP de origen entrantes", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Una instancia administrada (SQL MI) se puede aislar dentro de una red virtual para evitar el acceso externo. Las aplicaciones y herramientas que se encuentran en la misma red virtual o emparejada en la misma región podrían acceder a ella directamente. Las aplicaciones y herramientas que se encuentran en diferentes regiones podrían usar la conexión de red virtual a red virtual o el emparejamiento de circuitos ExpressRoute para establecer la conexión. El cliente debe usar grupos de seguridad de red (NSG) y, finalmente, firewalls internos, para restringir el acceso a través del puerto 1433 solo a los recursos que requieren acceso a una instancia administrada.", + "description": "Una instancia administrada (SQL MI) se puede aislar dentro de una red virtual para evitar el acceso externo. Las aplicaciones y herramientas que se encuentran en la misma red virtual o emparejadas en la misma región podrían acceder a ella directamente. Las aplicaciones y herramientas que se encuentran en diferentes regiones podrían usar la conexión de red virtual a red virtual o el emparejamiento de circuitos ExpressRoute para establecer la conexión. El cliente debe usar grupos de seguridad de red (NSG) y, finalmente, firewalls internos para restringir el acceso a través del puerto 1433 solo a los recursos que requieren acceso a una instancia administrada.", "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", "severity": "Medio", "subcategory": "Acceso privado", - "text": "Aplicación de grupos de seguridad de red (NSG) y reglas de firewall para restringir el acceso a la subred interna de Azure SQL Managed Instance" + "text": "Aplicación de grupos de seguridad de red (NSG) y reglas de firewall para restringir el acceso a la subred interna de Azure SQL Managed Instance", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Azure Virtual Network Service Endpoint es la solución preferida si desea establecer una conexión directa con los nodos back-end de Base de datos SQL de Azure mediante la directiva Redirect. Esto permitirá el acceso en modo de alto rendimiento y es el enfoque recomendado desde una perspectiva de rendimiento.", + "description": "El punto de conexión de servicio de red virtual de Azure es la solución preferida si desea establecer una conexión directa con los nodos de back-end de Azure SQL Database mediante la directiva de redireccionamiento. Esto permitirá el acceso en modo de alto rendimiento y es el enfoque recomendado desde el punto de vista del rendimiento.", "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", "severity": "Alto", "subcategory": "Acceso público", - "text": "Si se usa la conectividad de acceso público, aproveche Service Endpoint para restringir el acceso desde redes virtuales de Azure seleccionadas" + "text": "Si se usa la conectividad de acceso público, aproveche el punto de conexión de servicio para restringir el acceso desde las redes virtuales de Azure seleccionadas", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "El firewall de Base de datos SQL de Azure permite especificar intervalos de direcciones IP desde los que se aceptan las comunicaciones. Este enfoque está bien para direcciones IP estables que están fuera de la red privada de Azure.", + "description": "El firewall de Azure SQL Database permite especificar intervalos de direcciones IP desde los que se aceptan comunicaciones. Este enfoque es adecuado para direcciones IP estables que están fuera de la red privada de Azure.", "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "Medio", "subcategory": "Acceso público", - "text": "Si se usa conectividad de acceso público, asegúrese de que solo se agreguen IP conocidas específicas al firewall." + "text": "Si se utiliza la conectividad de acceso público, asegúrese de que solo se agreguen direcciones IP conocidas específicas al firewall", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Se recomienda utilizar reglas de firewall IP de nivel de base de datos siempre que sea posible. Esta práctica mejora la seguridad y hace que su base de datos sea más portátil. Utilice reglas de firewall IP de nivel de servidor para los administradores. Utilícelos también cuando tenga muchas bases de datos que tengan los mismos requisitos de acceso y no desee configurar cada base de datos individualmente.", + "description": "Le recomendamos que utilice reglas de firewall de IP a nivel de base de datos siempre que sea posible. Esta práctica mejora la seguridad y hace que su base de datos sea más portátil. Utilice reglas de firewall de IP de nivel de servidor para los administradores. Úselos también cuando tenga muchas bases de datos que tengan los mismos requisitos de acceso y no desee configurar cada base de datos individualmente.", "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", "severity": "Bajo", "subcategory": "Acceso público", - "text": "Si las reglas de firewall de Base de datos SQL de Azure usan y controlan la conectividad de acceso público, use reglas IP de nivel de base de datos sobre de nivel de servidor" + "text": "Si las reglas de firewall de Azure SQL Database usan y controlan la conectividad de acceso público, use reglas de IP de nivel de base de datos en lugar de reglas de IP de nivel de servidor", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Una instancia administrada (SQL MI) se puede aislar dentro de una red virtual para evitar el acceso externo. El punto de enlace público de instancia administrada no está habilitado de forma predeterminada, debe habilitarse explícitamente, solo si es estrictamente necesario. Si la directiva de la empresa no permite el uso de puntos de conexión públicos, use Azure Policy para evitar la habilitación de puntos de conexión públicos en primer lugar.", + "description": "Una instancia administrada (SQL MI) se puede aislar dentro de una red virtual para evitar el acceso externo. El punto de conexión público de Managed Instance no está habilitado de forma predeterminada, debe habilitarse explícitamente, solo si es estrictamente necesario. Si la directiva de la empresa no permite el uso de puntos de conexión públicos, use Azure Policy para evitar la habilitación de puntos de conexión públicos en primer lugar.", "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "Alto", "subcategory": "Acceso público", - "text": "No habilitar el punto de conexión público de Azure SQL Managed Instance" + "text": "No habilitar el punto de conexión público de Azure SQL Managed Instance", + "waf": "Seguridad" }, { "category": "Gestión de redes", - "description": "Un extremo público de instancia administrada (SQL MI) no está habilitado de forma predeterminada, debe habilitarse explícitamente, solo si es estrictamente necesario. En este caso, se recomienda aplicar un grupo de seguridad de red (NSG) para restringir el acceso al puerto 3342 solo a las direcciones IP de origen de confianza.", + "description": "Un punto de conexión público de Managed Instance (SQL MI) no está habilitado de forma predeterminada, debe estar habilitado explícitamente, solo si es estrictamente necesario. En este caso, se recomienda aplicar grupos de seguridad de red (NSG) para restringir el acceso al puerto 3342 solo a las direcciones IP de origen de confianza.", "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "Alto", "subcategory": "Acceso público", - "text": "Restringir el acceso si se requiere un punto de conexión público de Azure SQL Managed Instance" + "text": "Restrinja el acceso si se requiere el punto de conexión público de Azure SQL Managed Instance", + "waf": "Seguridad" }, { "category": "Acceso privilegiado", - "description": "La mayoría de las operaciones, el soporte técnico y la solución de problemas realizados por el personal y los subprocesadores de Microsoft no requieren acceso a los datos del cliente. En las raras circunstancias en las que se requiere dicho acceso, Customer Lockbox for Microsoft Azure proporciona una interfaz para que los clientes revisen y aprueben o rechacen las solicitudes de acceso a los datos del cliente. En escenarios de soporte técnico en los que Microsoft necesita acceder a los datos del cliente, Base de datos SQL de Azure admite Customer Lockbox para proporcionar una interfaz para que pueda revisar y aprobar o rechazar las solicitudes de acceso a datos del cliente.", + "description": "La mayoría de las operaciones, el soporte técnico y la solución de problemas realizados por el personal y los subprocesadores de Microsoft no requieren acceso a los datos del cliente. En las raras circunstancias en las que se requiere dicho acceso, Caja de seguridad del cliente para Microsoft Azure proporciona una interfaz para que los clientes revisen y aprueben o rechacen las solicitudes de acceso a los datos del cliente. En escenarios de soporte técnico en los que Microsoft necesita acceder a los datos de los clientes, Azure SQL Database admite la Caja de seguridad del cliente para proporcionar una interfaz para revisar y aprobar o rechazar las solicitudes de acceso a los datos de los clientes.", "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", "severity": "Bajo", "subcategory": "Caja", - "text": "Revisión y habilitación del acceso de Microsoft a Customer Lockbox para Azure SQL Database" + "text": "Revise y habilite la casilla de seguridad del cliente para el acceso a Azure SQL Database por parte del personal de Microsoft", + "waf": "Seguridad" }, { "category": "Acceso privilegiado", - "description": "El principio de privilegios mínimos establece que los usuarios no deben tener más privilegios de los necesarios para completar sus tareas. Los usuarios de bases de datos y servidores con privilegios altos pueden realizar muchas actividades de configuración y mantenimiento en la base de datos y también pueden quitar bases de datos en la instancia de Azure SQL. El seguimiento de los propietarios de bases de datos y las cuentas privilegiadas es importante para evitar tener permisos excesivos.", + "description": "El principio de privilegios mínimos establece que los usuarios no deben tener más privilegios de los necesarios para completar sus tareas. Los usuarios de bases de datos y servidores con privilegios elevados pueden realizar muchas actividades de configuración y mantenimiento en la base de datos y también pueden quitar bases de datos en la instancia de Azure SQL. El seguimiento de los propietarios de bases de datos y las cuentas privilegiadas es importante para evitar tener permisos excesivos.", "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", "severity": "Medio", "subcategory": "Permisos", - "text": "Asegúrese de que a los usuarios se les asigne el nivel mínimo de acceso necesario para completar sus funciones de trabajo" + "text": "Garantizar que a los usuarios se les asigne el nivel mínimo de acceso necesario para completar sus funciones laborales", + "waf": "Seguridad" }, { "category": "Acceso privilegiado", - "description": "El ámbito de las identidades (tanto Usuarios como SPN) debe tener la menor cantidad de acceso necesaria para realizar la función. Se debe usar un mayor número de SPN de ámbito estricto, en lugar de tener un SPN con varios conjuntos de permisos no relacionados. Por ejemplo, si hay tres aplicaciones web externas hospedadas localmente que realizan consultas a Base de datos SQL de Azure, no todas deben usar el mismo SPN para estas actividades. En su lugar, cada uno debe tener su propio SPN de alcance estricto.", + "description": "Las identidades (tanto los usuarios como los SPN) deben limitarse a la menor cantidad de acceso necesaria para realizar la función. Se debe usar un mayor número de SPN de ámbito estricto, en lugar de tener una SPN con varios conjuntos de permisos no relacionados. Por ejemplo, si hay tres aplicaciones web externas hospedadas localmente que realizan consultas a Azure SQL Database, no todas deben usar el mismo SPN para estas actividades. En su lugar, cada uno debe tener su propio SPN de ámbito estricto.", "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", "severity": "Bajo", "subcategory": "Permisos", - "text": "Asegúrese de que a distintas aplicaciones se les asignarán credenciales diferentes con permisos mínimos para acceder a Base de datos SQL de Azure." + "text": "Asegúrese de que a las distintas aplicaciones se les asignarán diferentes credenciales con permisos mínimos para acceder a Azure SQL Database", + "waf": "Seguridad" } ], "metadata": { - "name": "Azure SQLDB Security Checklist (Preview)" + "name": "Azure SQLDB Security Checklist (Preview)", + "state": "Preview", + "timestamp": "October 23, 2024" }, "severities": [ { @@ -502,16 +601,41 @@ "name": "Abrir" }, { - "description": "Esta comprobación se ha comprobado y no hay más elementos de acción asociados a ella", + "description": "Esta comprobación se ha verificado y no hay más elementos de acción asociados a ella", "name": "Cumplido" }, { - "description": "Recomendación entendida, pero no necesaria por los requisitos actuales", + "description": "Recomendación comprendida, pero no necesaria por los requisitos actuales", "name": "No es necesario" }, { "description": "No aplicable para el diseño actual", "name": "N/A" } + ], + "waf": [ + { + "name": "Fiabilidad" + }, + { + "name": "Seguridad" + }, + { + "name": "Costar" + }, + { + "name": "Operaciones" + }, + { + "name": "Rendimiento" + } + ], + "yesno": [ + { + "name": "Sí" + }, + { + "name": "No" + } ] } \ No newline at end of file diff --git a/checklists/sqldb_checklist.ja.json b/checklists/sqldb_checklist.ja.json index e80ed573..15fafe86 100644 --- a/checklists/sqldb_checklist.ja.json +++ b/checklists/sqldb_checklist.ja.json @@ -1,8 +1,7 @@ { - "$schema": "checklist.schema.json", "categories": [ { - "name": "ティッカー" + "name": "BCDRの" }, { "name": "ディフェンダー" @@ -37,449 +36,549 @@ ], "items": [ { - "category": "ティッカー", - "description": "バックアップが攻撃から保護されていることを確認します。これには、機密性の損失から保護するためのバックアップの暗号化を含める必要があります。通常の Azure サービス バックアップの場合、バックアップ データは Azure プラットフォーム マネージド キーを使用して自動的に暗号化されます。カスタマー マネージド キーを使用してバックアップを暗号化することもできます。この場合は、キー コンテナー内のこのカスタマー マネージド キーもバックアップ スコープ内にあることを確認します。", + "category": "BCDRの", + "description": "バックアップが攻撃から保護されていることを確認してください。これには、機密性の損失から保護するためのバックアップの暗号化を含める必要があります。通常の Azure サービス バックアップの場合、バックアップ データは Azure プラットフォーム マネージド キーを使用して自動的に暗号化されます。また、カスタマー マネージド キーを使用してバックアップを暗号化することもできます。この場合は、キー コンテナー内のこのカスタマー マネージド キーもバックアップ スコープ内にあることを確認します。", "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", "severity": "中程度", "subcategory": "Azure Key Vault", - "text": "バックアップ データを暗号化で保護し、キーを Azure Key Vault に安全に格納する" + "text": "バックアップ データを暗号化で保護し、キーを Azure Key Vault に安全に格納します", + "waf": "安全" }, { - "category": "ティッカー", - "description": "Azure SQL Database では、SQL Server テクノロジを使用して、毎週完全バックアップ、12 時間から 24 時間ごとの差分バックアップ、5 分から 10 分ごとにトランザクション ログ バックアップを作成します。既定では、SQL Database は、ペアのリージョンにレプリケートされる geo 冗長ストレージ BLOB にデータを格納します。", + "category": "BCDRの", + "description": "Azure SQL Database では、SQL Server テクノロジを使用して、完全バックアップを毎週作成し、差分バックアップを 12 時間から 24 時間ごとに作成し、トランザクション ログのバックアップを 5 分から 10 分ごとに作成します。既定では、SQL Database は、ペアのリージョンにレプリケートされる geo 冗長ストレージ BLOB にデータを格納します。", "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", "severity": "中程度", "subcategory": "バックアップ", - "text": "Azure SQL データベースの自動バックアップを構成する" + "text": "Azure SQL Database の自動バックアップを構成する", + "waf": "安全" }, { - "category": "ティッカー", - "description": "既定では、SQL Database は、ペアのリージョンにレプリケートされる geo 冗長ストレージ BLOB にデータを格納します。SQL Database の場合、バックアップ ストレージの冗長性は、データベースの作成時に構成することも、既存のデータベース用に更新することもできます。既存のデータベースに加えられた変更は、今後のバックアップにのみ適用されます。", + "category": "BCDRの", + "description": "既定では、SQL Database は、ペアのリージョンにレプリケートされる geo 冗長ストレージ BLOB にデータを格納します。SQL Database の場合、バックアップ ストレージの冗長性は、データベースの作成時に構成することも、既存のデータベースに対して更新することもできます。既存のデータベースに加えた変更は、将来のバックアップにのみ適用されます。", "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", "severity": "低い", "subcategory": "バックアップ", - "text": "geo 冗長バックアップ ストレージを有効にして、単一リージョンの障害やデータ損失から保護" + "text": "geo 冗長バックアップ ストレージを有効にして、単一リージョンの障害やデータ損失から保護します", + "waf": "安全" }, { "category": "コード", - "description": "悪意のあるコードは、セキュリティ制御を回避する可能性があります。カスタム コードを運用環境にデプロイする前に、デプロイされている内容を確認することが不可欠です。ソース管理をサポートする Azure Data Studio などのデータベース ツールを使用します。コード分析、脆弱性、および資格情報のスキャンのためのツールとロジックを実装します。", + "description": "悪意のあるコードは、セキュリティ制御を回避する可能性があります。カスタムコードを本番環境にデプロイする前に、デプロイされている内容を確認することが不可欠です。ソース管理をサポートする Azure Data Studio などのデータベース ツールを使用します。コード分析、脆弱性、および資格情報のスキャンのためのツールとロジックを実装します。", "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "中程度", - "subcategory": "ソース管理とコード レビュー", - "text": "ソース管理システムを使用して、Azure SQLDB データベース内にデプロイされたアプリケーション コードを格納、保守、およびレビューする" + "subcategory": "ソース管理とコードレビュー", + "text": "ソース管理システムを使用して、Azure SQLDB Database 内にデプロイされたアプリケーション コードを格納、保守、レビューします", + "waf": "安全" }, { "category": "データの検出と分類", - "description": "分類要件の場合は、Purview が推奨されるオプションです。SQL Data Discovery & Classification は、Purview がオプションではない場合にのみ使用してください。機密データが含まれている可能性のある列を検出します。機密データと見なされるものは、顧客、コンプライアンス規制などに大きく依存し、そのデータを担当するユーザーが評価する必要があります。高度な秘密度ベースの監査と保護のシナリオを使用するように列を分類します。自動検出の結果を確認し、必要に応じて分類を確定します。", + "description": "分類要件がある場合は、Purview が推奨されるオプションです。SQL Data Discovery & Classification は、Purview がオプションにない場合にのみ使用してください。機密データが含まれている可能性のある列を検出します。何がセンシティブなデータとみなされるかは、顧客やコンプライアンス規制などによって大きく異なり、そのデータを担当するユーザーが評価する必要があります。高度な感度ベースの監査と保護のシナリオを使用するように列を分類します。自動検出の結果を確認し、必要に応じて分類を確定します。", "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", "severity": "低い", "subcategory": "データの検出と分類", - "text": "機密データを保護するためのデータ検出と分類の計画と構成" + "text": "機密データを保護するためのデータ検出と分類の計画と構成", + "waf": "安全" }, { "category": "データマスキング", - "description": "この機能の使用は、列の暗号化がオプションではなく、データ型と形式を保持するための特定の要件がある場合にのみ推奨されます。動的データ マスクは、特権のないユーザーに機密データをマスクすることで、機密データの露出を制限します。動的データ マスクは、アプリケーション レイヤーへの影響を最小限に抑えながら、公開する機密データの量を指定することで、機密データへの不正アクセスを防ぐのに役立ちます。", + "description": "この機能の使用は、列の暗号化がオプションではなく、データ型と形式を保持するための特定の要件がある場合にのみ使用することをお勧めします。動的データマスキングは、機密データを非特権ユーザーにマスキングすることで、機密データの露出を制限します。動的データマスキングは、アプリケーション層への影響を最小限に抑えながら、公開する機密データの量をお客様が指定できるようにすることで、機密データへの不正アクセスを防ぐのに役立ちます。", "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", "severity": "低い", "subcategory": "データマスキング", - "text": "データマスキングを使用して、暗号化が不可能な場合に管理者以外の不正なユーザーのデータアクセスを防止します" + "text": "データマスキングを使用して、権限のない管理者以外のユーザーのデータアクセスを防止します(暗号化が不可能な場合)", + "waf": "安全" }, { "category": "ディフェンダー", - "description": "SQL 高度な脅威検出 (ATP) は、SQL インジェクション攻撃や異常な動作パターンなど、データベース内の潜在的な脆弱性や異常なアクティビティを検出するセキュリティ レイヤーを提供します。潜在的な脅威が検出されると、脅威検出は、電子メールと Microsoft Defender for Cloud で、特定の脅威に対する明確な調査と修復の手順を含む、実用的なリアルタイム アラートを送信します。", + "description": "SQL Advanced Threat Detection (ATP) は、SQL インジェクション攻撃や異常な動作パターンなど、データベース内の潜在的な脆弱性や異常なアクティビティを検出するセキュリティレイヤーを提供します。潜在的な脅威が検出されると、脅威検出は、特定の脅威に対する明確な調査と修復手順を含む、アクション可能なリアルタイム アラートを電子メールと Microsoft Defender for Cloud で送信します。", "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "高い", "subcategory": "高度な脅威対策", - "text": "高度な脅威対策 (ATP) の構成を確認して完了する" + "text": "Advanced Threat Protection (ATP) の設定を確認して完了します", + "waf": "安全" }, { "category": "ディフェンダー", - "description": "サブスクリプション レベルで Microsoft Defender for Azure SQL を有効にして、既存および将来のすべてのサーバーとデータベースを自動的にオンボードして保護します。サブスクリプション レベルで有効にすると、Azure SQL データベースと Azure SQL マネージド インスタンス内のすべてのデータベースが保護されます。その後、必要に応じて個別に無効にすることができます。保護するデータベースを手動で管理する場合は、サブスクリプション レベルで無効にし、保護する各データベースを有効にします。", + "description": "サブスクリプション レベルで Microsoft Defender for Azure SQL を有効にすると、既存および将来のすべてのサーバーとデータベースが自動的にオンボードされ、保護されます。サブスクリプション レベルで有効にすると、Azure SQL Database と Azure SQL Managed Instance のすべてのデータベースが保護されます。その後、必要に応じて個別に無効にすることができます。保護するデータベースを手動で管理する場合は、サブスクリプション レベルで無効にし、保護する各データベースを有効にします。", "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", "severity": "高い", "subcategory": "Defender for Azure SQL", - "text": "Enable Microsoft Defender for Azure SQL" + "text": "Microsoft Defender for Azure SQL を有効にする", + "waf": "安全" }, { "category": "ディフェンダー", - "description": "Microsoft Defender for Azure SQL ATP は、データベースにアクセスまたは悪用しようとする異常で潜在的に有害な試みを示す異常なアクティビティを検出します。アラートは構成および生成でき、コンソールの Defender で報告されます。", + "description": "Microsoft Defender for Azure SQL ATP は、データベースへのアクセスやデータベースの悪用を試みる、害を及ぼす可能性のある異常なアクティビティを検出します。アラートは構成および生成でき、Defender for console で報告されます。", "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "高い", "subcategory": "Defender for Azure SQL", - "text": "Microsoft Defender for Azure SQL アラートに迅速に対応するためのセキュリティ対応計画を準備する" + "text": "Microsoft Defender for Azure SQL アラートに迅速に対応するためのセキュリティ対応計画を準備する", + "waf": "安全" }, { "category": "ディフェンダー", - "description": "Azure SQLDB の脆弱性評価は、セキュリティ状態を可視化するサービスです。脆弱性評価には、セキュリティの問題を解決し、データベースのセキュリティを強化するための実用的な手順が含まれます。これは、変更の追跡が困難な動的データベース環境を監視し、SQL セキュリティ体制を改善するのに役立ちます。", + "description": "Azure SQLDB 脆弱性評価は、セキュリティの状態を可視化するサービスです。脆弱性評価には、セキュリティの問題を解決し、データベースのセキュリティを強化するための実行可能な手順が含まれます。これは、変更の追跡が困難な動的データベース環境を監視し、SQL セキュリティ体制を改善するのに役立ちます。", "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", "severity": "高い", - "subcategory": "脆弱性診断", - "text": "脆弱性評価 (VA) の結果を構成し、推奨事項を確認する" + "subcategory": "脆弱性評価", + "text": "脆弱性評価 (VA) の結果の構成と推奨事項の確認", + "waf": "安全" }, { "category": "ディフェンダー", - "description": "Microsoft Defender for Cloud は、Azure SQL Database の脆弱性評価を提供します。脆弱性評価は、データベースでソフトウェアの脆弱性をスキャンし、結果のリストを提供します。検出結果を使用して、ソフトウェアの脆弱性を修正し、検出結果を無効にすることができます。", + "description": "Microsoft Defender for Cloud は、Azure SQL Database の脆弱性評価を提供します。脆弱性評価では、データベースでソフトウェアの脆弱性がスキャンされ、結果のリストが表示されます。結果を使用して、ソフトウェアの脆弱性を修復し、結果を無効にすることができます。", "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", "severity": "高い", - "subcategory": "脆弱性診断", - "text": "脆弱性評価 (VA) の調査結果と推奨事項を定期的に確認し、修正計画を準備する" + "subcategory": "脆弱性評価", + "text": "脆弱性評価(VA)の調査結果と推奨事項を定期的にレビューし、修正計画を準備する", + "waf": "安全" }, { "category": "暗号化", - "description": "セキュリティで保護されたエンクレーブを使用した Always Encrypted は、インプレース暗号化とより豊富な機密クエリを有効にすることで、Always Encrypted の機密コンピューティング機能を拡張します。Always Encrypted with Secure Enclaves は、サーバー側のセキュリティで保護されたエンクレーブ内のプレーンテキスト データに対する計算を許可することで、これらの制限に対処します。この機能の使用は、管理者アクセスを制限する必要があり、暗号化された列の等価一致以上のものをクエリでサポートする必要がある場合に推奨されます。", + "description": "Secure Enclaves を使用した Always Encrypted は、インプレース暗号化とより豊富な機密クエリを有効にすることで、Always Encrypted の機密コンピューティング機能を拡張します。Always Encrypted with Secure Enclaves は、サーバー側のセキュア エンクレーブ内のプレーンテキスト データに対する一部の計算を許可することで、これらの制限に対処します。この機能の使用は、管理者アクセスを制限する必要があり、暗号化された列の等価一致以上のものをクエリでサポートする必要がある場合に推奨されます。", "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", "severity": "中程度", "subcategory": "常に暗号化", - "text": "管理者ユーザーから機密性の高い PII データを保護することが重要な要件であるが、列暗号化の制限が許容できない場合は、セキュリティで保護されたエンクレーブで常に暗号化される" + "text": "機密性の高い PII データを管理者ユーザーから保護することが重要な要件であるが、列暗号化の制限が許容できない場合は、Secure Enclaves を使用した Always Encrypted の採用を検討してください", + "waf": "安全" }, { "category": "暗号化", - "description": "Azure SQL データベースでは、Transact-SQL を使用してデータの列に対称暗号化を適用できます。この方法は、異なる暗号化キーを使用して特定の列を暗号化できるため、列の暗号化と呼ばれます。これにより、ページ内のデータを暗号化する TDE よりも詳細な暗号化機能が提供されます。Always Encrypted を使用して、メモリ内または使用中であっても、機密データが Azure SQL Database または SQL マネージド インスタンスでプレーンテキストで公開されないようにします。Always Encrypted は、データベース管理者 (DBA) やクラウド管理者 (または、高い特権を持つが承認されていないユーザーを偽装できる悪意のある人物) からデータを保護し、データにアクセスできるユーザーをより詳細に制御できるようにします。", + "description": "Azure SQL Database では、Transact-SQL を使用してデータの列に対称暗号化を適用できます。このアプローチは、異なる暗号化キーを持つ特定の列を暗号化するために使用できるため、列の暗号化と呼ばれます。これにより、ページ内のデータを暗号化する TDE よりも詳細な暗号化機能が提供されます。Always Encrypted を使用して、メモリ内または使用中であっても、機密データが Azure SQL Database または SQL Managed Instance でプレーンテキストで公開されないようにします。Always Encrypted は、データベース管理者 (DBA) やクラウド管理者 (または、高い特権を持つが権限のないユーザーになりすますことができる悪意のある人物) からデータを保護し、データにアクセスできるユーザーをより詳細に制御できるようにします。", "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", "severity": "低い", "subcategory": "列の暗号化", - "text": "特定のテーブル列の管理者以外のユーザーから機密性の高い PII データを保護するには、列の暗号化の使用を検討してください。" + "text": "特定のテーブル列で管理者以外のユーザーから機密性の高い PII データを保護するには、列の暗号化の使用を検討してください", + "waf": "安全" }, { "category": "暗号化", - "description": "既定で有効になっている透過的なデータ暗号化 (TDE) は、アプリケーションを変更することなく、データベース、関連するバックアップ、およびトランザクション ログ ファイルのリアルタイムの暗号化と暗号化解除を \"保存中\" で実行することで、データベース ファイルを情報漏えいから保護するのに役立ちます。", + "description": "デフォルトで有効になっている透過的データ暗号化(TDE)は、アプリケーションを変更することなく、データベース、関連するバックアップ、およびトランザクションログファイルの「保存中」の暗号化と復号化をリアルタイムで実行することにより、データベースファイルを情報漏えいから保護するのに役立ちます。", "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "高い", "subcategory": "透過的なデータ暗号化", - "text": "透過的なデータ暗号化 (TDE) が有効になっていることを確認する" + "text": "Transparent Data Encryption (TDE) が有効になっていることを確認します", + "waf": "安全" }, { "category": "暗号化", - "description": "組織内のキーとデータの管理における職務の分離が必要な場合は、Azure SQLDB の透過的なデータ暗号化 (TDE) にカスタマー マネージド キー (CMK) を活用し、Azure Key Vault を使用して格納します (チェックリストを参照)。この機能は、マネージド サービス キーでは満たすことができない厳格なセキュリティ要件がある場合に活用してください。", + "description": "組織内のキーとデータの管理で職務を分離する必要がある場合は、Azure SQLDB の Transparent Data Encryption (TDE) にカスタマー マネージド キー (CMK) を活用し、Azure Key Vault を使用して格納します (チェックリストを参照)。この機能は、管理されたサービス キーでは満たすことができない厳格なセキュリティ要件がある場合に活用します。", "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", "severity": "中程度", "subcategory": "透過的なデータ暗号化", - "text": "Azure Key Vault (AKV) でカスタマー マネージド キー (CMK) を使用する (TDE 保護の透明性を高め、きめ細かく制御する必要がある場合)" + "text": "TDE 保護の透明性を高め、きめ細かく制御する必要がある場合は、Azure Key Vault (AKV) でカスタマー マネージド キー (CMK) を使用します", + "waf": "安全" }, { "category": "暗号化", - "description": "トランスポート層セキュリティ (TLS) の最小バージョン設定を使用すると、お客様は SQL データベースで使用する TLS のバージョンを選択できます。TLS の最小バージョンは、Azure portal、Azure PowerShell、および Azure CLI を使用して変更できます。", + "description": "最小のトランスポート層セキュリティ (TLS) バージョン設定により、お客様は SQL データベースで使用する TLS のバージョンを選択できます。TLS の最小バージョンは、Azure portal、Azure PowerShell、Azure CLI を使用して変更できます。", "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", "severity": "高い", "subcategory": "トランスポート層セキュリティ", - "text": "TLS の最小バージョンを利用可能な最新のバージョンに適用する" + "text": "最小 TLS バージョンを利用可能な最新のバージョンに適用", + "waf": "安全" }, { "category": "同一性", - "description": "一元化された ID 管理のために Azure Active Directory (Azure AD) 認証を使用します。SQL 認証は、本当に必要な場合にのみ使用し、例外として文書化します。", + "description": "Azure Active Directory (Azure AD) 認証を使用して、ID を一元管理します。SQL 認証は本当に必要な場合にのみ使用し、例外として文書化します。", "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", "severity": "中程度", "subcategory": "Azure Active Directory", - "text": "Azure SQL データベースへの接続に Azure AD 認証を活用する" + "text": "Azure SQL Database への接続に Azure AD 認証を活用する", + "waf": "安全" }, { "category": "同一性", - "description": "Azure AD グループを使用すると、アクセス許可の管理が簡素化され、グループ所有者とリソース所有者の両方がグループにメンバーを追加したり、グループからメンバーを削除したりできます。論理サーバーごとに Azure AD 管理者用の個別のグループを作成します。Azure AD 監査アクティビティ レポートを使用して、Azure AD グループ メンバーシップの変更を監視します。", + "description": "Azure AD グループを使用すると、アクセス許可の管理が簡素化され、グループ所有者とリソース所有者の両方がグループに対してメンバーを追加/削除できます。論理サーバーごとに Azure AD 管理者用の個別のグループを作成します。Azure AD 監査アクティビティ レポートを使用して、Azure AD グループ メンバーシップの変更を監視します。", "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", "severity": "中程度", "subcategory": "Azure Active Directory", - "text": "Azure SQL データベース論理サーバーごとに 2 つの管理者アカウントを持つ個別の Azure AD グループを作成する" + "text": "Azure SQL Database 論理サーバーごとに 2 つの管理者アカウントを持つ個別の Azure AD グループを作成します", + "waf": "安全" }, { "category": "同一性", - "description": "Azure サービスおよびアプリケーションから Azure SQLDB データベースへの通信に、最小限のアクセス許可が割り当てられた、機能専用の個別のシステムおよびユーザー割り当てマネージド ID が使用されていることを確認します。", + "description": "Azure サービスとアプリケーションから Azure SQLDB データベースへの通信には、機能専用の個別のシステムとユーザー割り当てマネージド ID が最小限のアクセス許可で使用されていることを確認します。", "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", "severity": "中程度", "subcategory": "Azure Active Directory", - "text": "アプリケーションでのパスワードベースの認証の使用を最小限に抑える" + "text": "アプリケーションでのパスワードベースの認証の使用を最小限にする", + "waf": "安全" }, { "category": "同一性", - "description": "システムまたはユーザー割り当てマネージド ID を使用すると、Azure SQLDB は、資格情報をコードに格納することなく、他のクラウド サービス (Azure Key Vault など) に対する認証を行うことができます。有効にすると、必要なすべてのアクセス許可を、Azure ロールベースのアクセス制御を介して特定の Azure SQLDB インスタンスに付与できます。厳密に必要でない場合は、複数のサービス間でユーザー割り当てマネージド ID を共有しないでください。", + "description": "システムまたはユーザー割り当てマネージド ID を使用すると、Azure SQLDB は、コードに資格情報を格納せずに、他のクラウド サービス (Azure Key Vault など) に対して認証を行うことができます。有効にすると、必要なすべてのアクセス許可を Azure ロールベースのアクセス制御を介して特定の Azure SQLDB インスタンスに付与できます。厳密に必要でない場合は、ユーザー割り当てマネージド ID を複数のサービス間で共有しないでください。", "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "severity": "低い", "subcategory": "マネージド ID", - "text": "Azure SQL データベースに送信リソース アクセス用のマネージド ID を割り当てる" + "text": "Azure SQL Database に送信リソース アクセス用のマネージド ID を割り当てる", + "waf": "安全" }, { "category": "同一性", - "description": "パスワードの使用を排除する Azure AD 統合認証を使用します。パスワードベースの認証方法は、認証の弱い形式です。資格情報が侵害されたり、誤って譲渡されたりする可能性があります。Windows 資格情報を使用したシングル サインオン認証を使用します。オンプレミスの AD ドメインを Azure AD とフェデレーションし、統合 Windows 認証を使用します (Azure AD を持つドメインに参加しているマシンの場合)。", + "description": "パスワードの使用を排除する Azure AD 統合認証を使用します。パスワードベースの認証方法は、認証の弱い形式です。資格情報が侵害されたり、誤って提供されたりする可能性があります。Windows 資格情報を使用したシングル サインオン認証を使用します。オンプレミスの AD ドメインを Azure AD とフェデレーションし、統合 Windows 認証を使用します (Azure AD とドメインに参加しているマシンの場合)。", "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", "severity": "中程度", "subcategory": "パスワード", - "text": "ユーザーのパスワードベースの認証の使用を最小限に抑える" + "text": "ユーザーのパスワードベースの認証の使用を最小限に抑える", + "waf": "安全" }, { "category": "台帳", - "description": "データベース台帳内の最新のブロックのハッシュは、データベースダイジェストと呼ばれます。これは、ブロックが生成された時点でのデータベース内のすべての台帳テーブルの状態を表します。データベース ダイジェストの生成は、最近追加されたブロックのハッシュのみを計算する必要があるため、効率的です。Azure 社外秘台帳はサポートされているストアの 1 つであり、データベース ダイジェストの自動生成と格納をサポートして使用できます。Azure Ledger には、ブロックチェーン元帳証明や機密ハードウェア エンクレーブなどの高度なセキュリティ機能が用意されています。高度なセキュリティ機能が必要な場合にのみ使用し、それ以外の場合は Azure ストレージに戻します。", + "description": "データベース台帳内の最新のブロックのハッシュは、データベースダイジェストと呼ばれます。これは、ブロックが生成された時点のデータベース内のすべての台帳テーブルの状態を表します。データベース ダイジェストの生成は、最近追加されたブロックのハッシュのみを計算する必要があるため、効率的です。Azure Confidential Ledger はサポートされているストアの 1 つであり、使用でき、データベース ダイジェストの自動生成と保存をサポートしています。Azure Ledger には、Blockchain Ledger Proof や Confidential Hardware Enclaves などの高度なセキュリティ機能が用意されています。高度なセキュリティ機能が必要な場合にのみ使用し、それ以外の場合は Azure Storage に戻します。", "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", "severity": "中程度", "subcategory": "データベースダイジェスト", - "text": "Azure 機密元帳を使用してデータベース ダイジェストを格納するのは、高度なセキュリティ機能が必要な場合のみにしてください。" + "text": "Azure Confidential Ledger を使用してデータベース ダイジェストを格納するのは、高度なセキュリティ機能が必要な場合のみです", + "waf": "安全" }, { "category": "台帳", - "description": "データベース台帳内の最新のブロックのハッシュは、データベースダイジェストと呼ばれます。これは、ブロックが生成された時点でのデータベース内のすべての台帳テーブルの状態を表します。データベース ダイジェストの生成は、最近追加されたブロックのハッシュのみを計算する必要があるため、効率的です。不変ストレージを使用した Azure BLOB ストレージ機能は使用でき、データベース ダイジェストの自動生成とストレージをサポートします。ダイジェストファイルの改ざんを防ぐには、コンテナーのアイテム保持ポリシーを構成してロックします。", + "description": "データベース台帳内の最新のブロックのハッシュは、データベースダイジェストと呼ばれます。これは、ブロックが生成された時点のデータベース内のすべての台帳テーブルの状態を表します。データベース ダイジェストの生成は、最近追加されたブロックのハッシュのみを計算する必要があるため、効率的です。イミュータブル ストレージ機能を備えた Azure Blob Storage は使用でき、データベース ダイジェストの自動生成と保存をサポートします。ダイジェスト ファイルの改ざんを防ぐには、コンテナーの保持ポリシーを構成してロックします。", "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", "severity": "中程度", "subcategory": "データベースダイジェスト", - "text": "Azure ストレージ アカウントを使用してデータベース ダイジェストを格納する場合は、セキュリティが適切に構成されていることを確認する" + "text": "Azure ストレージ アカウントを使用してデータベース ダイジェストを格納する場合は、セキュリティが適切に構成されていることを確認してください", + "waf": "安全" }, { "category": "台帳", - "description": "Ledgerは、前方整合性と呼ばれるデータ整合性の形式を提供し、台帳テーブル内のデータのデータ改ざんの証拠を提供します。データベース検証プロセスは、以前に生成された 1 つ以上のデータベース ダイジェストを入力として受け取ります。次に、台帳テーブルの現在の状態に基づいて、データベース台帳に格納されているハッシュを再計算します。計算されたハッシュが入力ダイジェストと一致しない場合、検証は失敗します。このエラーは、データが改ざんされたことを示します。検証プロセスでは、検出されたすべての不整合が報告されます。", + "description": "台帳には、フォワード整合性と呼ばれるデータ整合性の形式があり、台帳テーブル内のデータに対するデータの改ざんの証拠を提供します。データベース検証プロセスでは、以前に生成された 1 つ以上のデータベース ダイジェストを入力として受け取ります。次に、台帳テーブルの現在の状態に基づいて、データベース台帳に保存されているハッシュを再計算します。計算されたハッシュが入力ダイジェストと一致しない場合、検証は失敗します。このエラーは、データが改ざんされたことを示しています。検証プロセスでは、検出されたすべての不整合が報告されます。", "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", "severity": "中程度", "subcategory": "整合性", - "text": "Ledgerの検証プロセスを定期的にスケジュールして、データの整合性を検証します" + "text": "Ledgerの検証プロセスを定期的にスケジュールして、データの整合性を確認します", + "waf": "安全" }, { "category": "台帳", - "description": "台帳機能は、データベースに改ざん証拠機能を提供します。監査人や他のビジネス関係者など、データが改ざんされていないことを他の関係者に暗号で証明できます。Ledgerは、データベース管理者(DBA)、システム管理者、クラウド管理者など、攻撃者や高い権限を持つユーザーからデータを保護するのに役立ちます。", + "description": "台帳機能は、データベースに改ざん証拠機能を提供します。監査人や他のビジネス関係者など、他の関係者に対して、データが改ざんされていないことを暗号で証明できます。Ledgerは、データベース管理者(DBA)、システム管理者、クラウド管理者など、攻撃者や高い権限を持つユーザーからデータを保護するのに役立ちます。", "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", "severity": "中程度", "subcategory": "台帳", - "text": "データ整合性の暗号化証明が重要な要件である場合は、Ledger機能を検討する必要があります" + "text": "データ整合性の暗号化証明が重要な要件である場合は、Ledger機能を検討する必要があります", + "waf": "安全" }, { "category": "台帳", - "description": "改ざんの種類によっては、データを失うことなく台帳を修復できる場合があります。「詳細情報」列に含まれる記事では、さまざまなシナリオと回復手法について説明します。", + "description": "改ざんの種類によっては、データを失うことなく台帳を修復できるケースもあります。「--詳細情報--」コラムに記載されている記事では、さまざまなシナリオと回復手法について説明しています。", "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", "severity": "中程度", "subcategory": "回復", - "text": "改ざんイベント後にデータベースを調査および修復するための対応計画を準備する" + "text": "改ざんイベント後にデータベースを調査して修復するための対応計画を準備する", + "waf": "安全" }, { "category": "伐採", - "description": "Azure SQL データベース監査は、データベース イベントを追跡し、Azure ストレージ アカウントの監査ログに書き込みます。監査は、データベースアクティビティを理解し、ビジネス上の懸念やセキュリティ違反の疑いを示す可能性のある不一致や異常に関する洞察を得るのに役立ち、規制コンプライアンスを満たすのに役立ちます。既定では、監査ポリシーにはデータベースに対するすべてのアクション (クエリ、ストアド プロシージャ、成功および失敗したログイン) が含まれているため、大量の監査ログが発生する可能性があります。PowerShell を使用して、さまざまな種類のアクションとアクション グループの監査を構成することをお勧めします。", + "description": "Azure SQL Database 監査は、データベース イベントを追跡し、Azure ストレージ アカウントの監査ログに書き込みます。監査は、データベース・アクティビティーを理解し、ビジネス上の懸念やセキュリティー違反の疑いを示す可能性のある不一致や異常に関する洞察を得るのに役立ち、規制コンプライアンスの達成にも役立ちます。デフォルトでは、監査ポリシーには、データベースに対するすべてのアクション (クエリ、ストアド・プロシージャ、成功および失敗したログイン) が含まれているため、監査ログが大量に発生する可能性があります。お客様は、PowerShell を使用してさまざまな種類のアクションとアクション グループの監査を構成することをお勧めします。", "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "中程度", "subcategory": "聴講", - "text": "Azure SQL データベース監査がサーバー レベルで有効になっていることを確認する" + "text": "Azure SQL Database の監査がサーバー レベルで有効になっていることを確認します", + "waf": "安全" }, { "category": "伐採", - "description": "Azure SQL データベース監査ログは、外部ストレージ アカウント、Log Analytics ワークスペース、またはイベント ハブに書き込むことができます。ターゲットリポジトリは、バックアップと安全な設定を使用して保護してください。Azure SQL データベース マネージド ID を使用してストレージにアクセスし、明示的な保有期間を設定します。監査ログリポジトリへのアクセス許可を管理者に付与しないでください。別のターゲット ストレージを使用する -- Microsoft サポート操作の監査を有効にします--.", + "description": "Azure SQL Database 監査ログは、外部ストレージ アカウント、Log Analytics ワークスペース、またはイベント ハブに書き込むことができます。ターゲットリポジトリは、バックアップと安全な設定を使用して保護してください。Azure SQL Database マネージド ID を使用してストレージにアクセスし、明示的な保持期間を設定します。監査ログリポジトリに対する権限を管理者に付与しないでください。--Microsoft サポート操作の監査を有効にするには、別のターゲット ストレージを使用します--.", "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "低い", "subcategory": "聴講", - "text": "Azure SQL データベース監査ログがバックアップされ、選択したリポジトリの種類でセキュリティで保護されていることを確認する" + "text": "Azure SQL Database 監査ログが、選択したリポジトリの種類でバックアップされ、セキュリティで保護されていることを確認します", + "waf": "安全" }, { "category": "伐採", - "description": "Azure Monitor アクティビティ ログは、サブスクリプション レベルのイベントに関する分析情報を提供する Azure のプラットフォーム ログです。アクティビティ ログには、リソースがいつ変更されたかなどの情報が含まれます。このアクティビティ ログは、Azure SQL データベース監査ログと同じ外部ストレージ リポジトリ (ストレージ アカウント、Log Analytics ワークスペース、イベント ハブ) に送信することをお勧めします。", + "description": "Azure Monitor アクティビティ ログは、サブスクリプション レベルのイベントに関する分析情報を提供する Azure のプラットフォーム ログです。アクティビティ ログには、リソースが変更された日時などの情報が含まれます。このアクティビティ ログは、Azure SQL Database 監査ログと同じ外部ストレージ リポジトリ (ストレージ アカウント、Log Analytics ワークスペース、イベント ハブ) に送信することをお勧めします。", "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "中程度", "subcategory": "聴講", - "text": "Azure SQL データベース アクティビティ ログが収集され、監査ログと統合されていることを確認する" + "text": "Azure SQL Database アクティビティ ログが収集され、監査ログと統合されていることを確認します", + "waf": "安全" }, { "category": "伐採", - "description": "Azure SQL からセキュリティ情報イベント管理 (SIEM) とセキュリティ オーケストレーションの自動化と応答 (SOAR) にログを転送します。さまざまな種類の Azure 資産を監視して、潜在的な脅威や異常がないことを確認します。アナリストが分類する誤検知を減らすために、高品質のアラートの取得に重点を置きます。アラートは、ログデータ、エージェント、またはその他のデータから取得できます。", + "description": "Azure SQL からのログを Security Information and Event Management (SIEM) と Security Orchestration Automation and Response (SOAR) に転送します。さまざまな種類の Azure 資産を監視して、潜在的な脅威や異常がないか確認します。アナリストが分類するための誤検知を減らすために、高品質のアラートを取得することに焦点を当てます。アラートは、ログ データ、エージェント、またはその他のデータから取得できます。", "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "中程度", - "subcategory": "シェム/ソア", - "text": "Azure SQL Database 監査ログが組織の SIEM/SOAR に提示されていることを確認する" + "subcategory": "SIEM/ソア", + "text": "Azure SQL Database 監査ログが組織の SIEM/SOAR に表示されていることを確認します", + "waf": "安全" }, { "category": "伐採", - "description": "Azure SQL からのログを、カスタム脅威検出の設定に使用できるセキュリティ情報イベント管理 (SIEM) とセキュリティ オーケストレーションの自動化と対応 (SOAR) に転送します。さまざまな種類の Azure 資産を監視して、潜在的な脅威や異常がないことを確認します。アナリストが分類する誤検知を減らすために、高品質のアラートの取得に重点を置きます。アラートは、ログデータ、エージェント、またはその他のデータから取得できます。", + "description": "Azure SQL からのログを Security Information and Event Management (SIEM) と Security Orchestration Automation and Response (SOAR) に転送し、カスタム脅威検出の設定に使用できます。さまざまな種類の Azure 資産を監視して、潜在的な脅威や異常がないか確認します。アナリストが分類するための誤検知を減らすために、高品質のアラートを取得することに焦点を当てます。アラートは、ログ データ、エージェント、またはその他のデータから取得できます。", "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "中程度", - "subcategory": "シェム/ソア", - "text": "Azure SQL データベース アクティビティ ログ データが SIEM/SOAR に表示されていることを確認する" + "subcategory": "SIEM/ソア", + "text": "Azure SQL Database アクティビティ ログ データが SIEM/SOAR に表示されていることを確認します", + "waf": "安全" }, { "category": "伐採", - "description": "セキュリティ オペレーション センター (SOC) チームは、インシデント対応計画 (プレイブックまたは手動対応) を作成して、改ざん、悪意のあるアクティビティ、およびその他の異常な動作を調査して軽減する必要があります。", + "description": "セキュリティ オペレーション センター (SOC) チームは、改ざん、悪意のあるアクティビティ、その他の異常な動作を調査して軽減するためのインシデント対応計画 (プレイブックまたは手動対応) を作成する必要があります。", "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "中程度", - "subcategory": "シェム/ソア", - "text": "悪意のある監査ログイベントまたは異常な監査ログ イベントに対する対応計画があることを確認する" + "subcategory": "SIEM/ソア", + "text": "悪意のあるまたは異常な監査ログ イベントに対する対応計画があることを確認します", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "Azure SQL データベース用の Azure portal から論理サーバーを作成すると、パブリック ネットワーク経由で表示および到達可能なパブリック エンドポイント (パブリック アクセス) が作成されます。その後、ファイアウォール規則とサービス エンドポイントに基づいて接続を制限できます。プライベート エンドポイント (プライベート アクセス) を使用して、内部ネットワークへの接続を制限するプライベート接続のみを構成することもできます。プライベート エンドポイントを使用したプライベート アクセスは、それをサポートできないビジネス ケースまたはパフォーマンス/技術的な理由が適用されない限り、既定にする必要があります。プライベート エンドポイントの使用には、考慮および評価する必要があるパフォーマンスへの影響があります。", + "description": "Azure portal から Azure SQL Database の論理サーバーを作成すると、パブリック ネットワーク経由で表示および到達可能なパブリック エンドポイントが作成されます (パブリック アクセス)。その後、ファイアウォール ルールとサービス エンドポイントに基づいて接続を制限できます。また、プライベートエンドポイント (プライベートアクセス) を使用して、内部ネットワークへの接続のみを制限するプライベート接続を構成することもできます。プライベートエンドポイントを使用したプライベートアクセスは、それをサポートできないビジネスケースまたはパフォーマンス/技術的な理由が適用されない限り、デフォルトにする必要があります。プライベートエンドポイントの使用には、考慮して評価する必要があるパフォーマンスへの影響があります。", "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "高い", "subcategory": "接続", - "text": "パブリック アクセスとプライベート アクセスの接続方法を確認し、ワークロードに適した接続方法を選択する" + "text": "パブリック アクセスとプライベート アクセスの接続方法を確認し、ワークロードに適した方法を選択します", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "重要: プライベート エンドポイントへの接続では、接続ポリシーとしてプロキシのみがサポートされます。プライベート エンドポイントを使用する場合、接続は Azure SQL Database ゲートウェイ経由でデータベース ノードにプロキシされます。クライアントは直接接続されません。", + "description": "重要: プライベートエンドポイントへの接続は、接続ポリシーとしてプロキシのみをサポートします。プライベート エンドポイントを使用する場合、接続は Azure SQL Database ゲートウェイを介してデータベース ノードにプロキシされます。クライアントには直接接続できません。", "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", "severity": "低い", "subcategory": "接続", - "text": "既定の Azure SQL データベース接続ポリシーを保持する (特に必要でなく、正当化されない場合)" + "text": "デフォルトの Azure SQL Database 接続ポリシーを保持する (異なる方法で必要で正当化されない場合)", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "このオプションは、他の顧客のサブスクリプションからの接続を含め、Azure からのすべての接続を許可するようにファイアウォールを構成します。このオプションを選択する場合は、ログイン権限とユーザー権限で、アクセスを許可されたユーザーのみに制限してください。厳密には必須でない場合は、この設定を OFF のままにします。", + "description": "このオプションでは、他の顧客のサブスクリプションからの接続を含む、Azure からのすべての接続を許可するようにファイアウォールを構成します。このオプションを選択する場合は、ログイン権限とユーザー権限がアクセスを許可されたユーザーのみに制限していることを確認してください。厳密には必要でない場合は、この設定を OFF のままにします。", "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "高い", "subcategory": "接続", - "text": "Azure サービスとリソースにこのサーバーへのアクセスを許可する設定が Azure SQL データベース ファイアウォールで無効になっていることを確認する" + "text": "Azure SQL Database ファイアウォールで [Azure サービスとリソースにこのサーバーへのアクセスを許可する] 設定が無効になっていることを確認します", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "Azure SQL データベースには、外部 REST エンドポイントとのネイティブ統合を可能にする新しい組み込み機能があります。これは、Azure SQL Database と Azure Functions、Azure Logic Apps、Cognitive Services、Event Hubs、Event Grid、Azure Containers、API Management、そして一般的には任意の REST または GraphQL エンドポイントとの統合を意味します。適切に制限されていない場合、Azure SQL データベース データベース内のコードは、このメカニズムを利用してデータを盗み出す可能性があります。厳密に必要でない場合は、送信ファイアウォール規則を使用してこの機能をブロックまたは制限することをお勧めします。", + "description": "Azure SQL Database には、外部 REST エンドポイントとのネイティブ統合を可能にする新しい組み込み機能があります。これは、Azure SQL Database と Azure Functions、Azure Logic Apps、Cognitive Services、Event Hubs、Event Grid、Azure Containers、API Management、および一般的には任意の REST または GraphQL エンドポイントとの統合を意味します。適切に制限されていない場合、Azure SQL Database データベース内のコードでこのメカニズムを利用してデータを流出させる可能性があります。厳密に必要でない場合は、アウトバウンドファイアウォールルールを使用してこの機能をブロックまたは制限することをお勧めします。", "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", "severity": "中程度", - "subcategory": "アウトバウンド制御", - "text": "外部エンドポイントへの送信 REST API 呼び出しをブロックまたは制限する" + "subcategory": "アウトバウンドコントロール", + "text": "外部エンドポイントへの送信 REST API 呼び出しをブロックまたは制限する", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "送信ファイアウォール規則は、Azure SQL データベース論理サーバーからのネットワーク トラフィックを、Azure ストレージ アカウントと Azure SQL データベース論理サーバーの顧客定義の一覧に制限します。この一覧にないストレージ アカウントまたはデータベースにアクセスしようとすると、拒否されます。", + "description": "送信ファイアウォール規則は、Azure SQL Database 論理サーバーからのネットワーク トラフィックを、Azure Storage アカウントと Azure SQL Database 論理サーバーの顧客定義の一覧に制限します。この一覧にないストレージ アカウントまたはデータベースへのアクセスの試行は拒否されます。", "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", "severity": "中程度", - "subcategory": "アウトバウンド制御", - "text": "送信ネットワーク アクセスが必要な場合は、組み込みの Azure SQL Database コントロール機能を使用して送信ネットワークの制限を構成することをお勧めします。" + "subcategory": "アウトバウンドコントロール", + "text": "送信ネットワーク アクセスが必要な場合は、組み込みの Azure SQL Database 制御機能を使用して送信ネットワーク制限を構成することをお勧めします", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "プライベート エンドポイントは、Azure 仮想ネットワーク内のサブネット内に作成されます。適切なセキュリティ構成は、NSG/ASG、UDR、ファイアウォール、監視、監査など、包含ネットワーク環境にも適用する必要があります。", + "description": "プライベート エンドポイントは、Azure Virtual Network のサブネット内に作成されます。適切なセキュリティ構成は、NSG/ASG、UDR、ファイアウォール、監視、監査など、包含するネットワーク環境にも適用する必要があります。", "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "中程度", "subcategory": "プライベートアクセス", - "text": "プライベート アクセス接続を使用する場合は、プライベート エンドポイント、Azure 仮想ネットワーク、Azure ファイアウォール、および Azure ネットワーク セキュリティ グループのチェックリストを使用していることを確認します。" + "text": "プライベート アクセス接続を使用する場合は、プライベート エンドポイント、Azure Virtual Network、Azure Firewall、Azure ネットワーク セキュリティ グループのチェックリストを使用していることを確認してください", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "プライベート エンドポイント接続を追加する場合、論理サーバーへのパブリック ルーティングは既定ではブロックされません。[-- ファイアウォールと仮想ネットワーク] ウィンドウでは、[パブリック ネットワーク アクセスを拒否する] 設定が既定では選択されていません。パブリックネットワークアクセスを無効にするには、必ず --パブリックネットワークアクセスを拒否する を選択します--.", + "description": "プライベート エンドポイント接続を追加する場合、論理サーバーへのパブリック ルーティングは既定ではブロックされません。[ファイアウォールと仮想ネットワーク] ウィンドウでは、設定 [パブリック ネットワーク アクセスを拒否する] は既定では選択されていません。パブリックネットワークアクセスを無効にするには、必ず「--パブリックネットワークアクセスを拒否する」を選択してください--.", "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "高い", "subcategory": "プライベートアクセス", - "text": "プライベート エンドポイント (プライベート アクセス) を使用する場合は、パブリック アクセス接続を無効にすることを検討してください。" + "text": "プライベートエンドポイント(プライベートアクセス)を使用する場合は、パブリックアクセス接続を無効にすることを検討してください", + "waf": "安全" }, { "category": "ネットワーキング", "description": "ネットワーク セキュリティ グループ (NSG) とアプリケーション セキュリティ グループ (ASG) をプライベート エンドポイントを含むサブネットに適用して、内部ソース IP 範囲に基づいて Azure SQLDB への接続を制限できるようになりました。", "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", "severity": "中程度", "subcategory": "プライベートアクセス", - "text": "プライベート エンドポイント (プライベート アクセス) を使用する場合は、NSG を適用し、最終的には ASG を適用して、受信ソース IP アドレス範囲を制限します。" + "text": "プライベート エンドポイント (プライベート アクセス) を使用する場合は、NSG を適用し、最終的には ASG を適用して、受信ソース IP アドレスの範囲を制限します", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "マネージド インスタンス (SQL MI) を仮想ネットワーク内に分離して、外部アクセスを防ぐことができます。同じリージョン内の同じ仮想ネットワークまたはピアリングされた仮想ネットワーク内にあるアプリケーションとツールは、直接アクセスできます。異なるリージョンにあるアプリケーションとツールは、仮想ネットワーク間接続または ExpressRoute 回線ピアリングを使用して接続を確立できます。お客様は、ネットワーク セキュリティ グループ (NSG) と最終的には内部ファイアウォールを使用して、ポート 1433 経由のアクセスをマネージド インスタンスへのアクセスを必要とするリソースのみに制限する必要があります。", + "description": "Managed Instance (SQL MI) は、外部アクセスを防ぐために仮想ネットワーク内で分離できます。同じリージョン内の同じ仮想ネットワークまたはピアリングされた仮想ネットワーク内にあるアプリケーションとツールは、直接アクセスできます。異なるリージョンにあるアプリケーションとツールは、仮想ネットワーク間接続または ExpressRoute 回線ピアリングを使用して接続を確立できます。お客様は、ネットワーク セキュリティ グループ (NSG) を使用し、最終的には内部ファイアウォールを使用して、ポート 1433 経由のアクセスをマネージド インスタンスへのアクセスを必要とするリソースのみに制限する必要があります。", "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", "severity": "中程度", "subcategory": "プライベートアクセス", - "text": "ネットワーク セキュリティ グループ (NSG) とファイアウォール規則を適用して、Azure SQL マネージド インスタンスの内部サブネットへのアクセスを制限する" + "text": "ネットワーク セキュリティ グループ (NSG) とファイアウォール規則を適用して、Azure SQL Managed Instance の内部サブネットへのアクセスを制限する", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "Azure 仮想ネットワーク サービス エンドポイントは、リダイレクト ポリシーを使用して Azure SQL Database バックエンド ノードへの直接接続を確立する場合に推奨されるソリューションです。これにより、高パフォーマンス モードでのアクセスが可能になり、パフォーマンスの観点から推奨されるアプローチです。", + "description": "Azure Virtual Network サービス エンドポイントは、リダイレクト ポリシーを使用して Azure SQL Database バックエンド ノードへの直接接続を確立する場合に適したソリューションです。これにより、高パフォーマンス モードでのアクセスが可能になり、パフォーマンスの観点から推奨されるアプローチです。", "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", "severity": "高い", "subcategory": "パブリックアクセス", - "text": "パブリック アクセス接続が使用されている場合は、サービス エンドポイントを利用して、選択した Azure 仮想ネットワークからのアクセスを制限します。" + "text": "パブリック アクセス接続を使用する場合は、サービス エンドポイントを活用して、選択した Azure Virtual Network からのアクセスを制限します", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "Azure SQL データベース ファイアウォールでは、通信を受け入れる IP アドレス範囲を指定できます。この方法は、Azure プライベート ネットワークの外部にある安定した IP アドレスに適しています。", + "description": "Azure SQL Database ファイアウォールでは、通信を受け入れる IP アドレス範囲を指定できます。この方法は、Azure プライベート ネットワークの外部にある安定した IP アドレスに適しています。", "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "中程度", "subcategory": "パブリックアクセス", - "text": "パブリック アクセス接続を使用する場合は、特定の既知の IP のみがファイアウォールに追加されていることを確認します。" + "text": "パブリックアクセス接続を使用する場合は、特定の既知のIPのみがファイアウォールに追加されていることを確認してください", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "可能な限り、データベース レベルの IP ファイアウォール規則を使用することをお勧めします。これにより、セキュリティが強化され、データベースの移植性が向上します。管理者にはサーバー レベルの IP ファイアウォール規則を使用します。また、同じアクセス要件を持つデータベースが多数あり、各データベースを個別に構成したくない場合にも使用します。", + "description": "可能な限り、データベースレベルの IP ファイアウォールルールを使用することをお勧めします。この方法により、セキュリティが強化され、データベースの移植性が向上します。管理者には、サーバーレベルの IP ファイアウォール規則を使用します。また、同じアクセス要件を持つデータベースが多数あり、各データベースを個別に構成したくない場合にも使用します。", "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", "severity": "低い", "subcategory": "パブリックアクセス", - "text": "パブリック アクセス接続が Azure SQL Database のファイアウォール規則によって使用および制御されている場合は、サーバー レベルの IP 規則よりもデータベース レベルの IP 規則を使用します。" + "text": "パブリック アクセス接続が Azure SQL Database ファイアウォール規則によって使用および制御されている場合は、データベース レベルとサーバー レベルの IP 規則を使用します", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "マネージド インスタンス (SQL MI) を仮想ネットワーク内に分離して、外部アクセスを防ぐことができます。マネージド インスタンスのパブリック エンドポイントは既定では有効になっていないため、厳密に必要な場合にのみ明示的に有効にする必要があります。会社のポリシーでパブリック エンドポイントの使用が許可されていない場合は、Azure Policy を使用して、最初にパブリック エンドポイントを有効にしないようにします。", + "description": "Managed Instance (SQL MI) は、外部アクセスを防ぐために仮想ネットワーク内で分離できます。Managed Instance パブリック エンドポイントは既定では有効になっていないため、厳密に必要な場合にのみ明示的に有効にする必要があります。会社のポリシーでパブリック エンドポイントの使用が許可されていない場合は、Azure Policy を使用して、最初にパブリック エンドポイントを有効にしないようにします。", "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "高い", "subcategory": "パブリックアクセス", - "text": "Azure SQL マネージド インスタンスのパブリック エンドポイントを有効にしない" + "text": "Azure SQL Managed Instance パブリック エンドポイントを有効にしない", + "waf": "安全" }, { "category": "ネットワーキング", - "description": "マネージド インスタンス (SQL MI) パブリック エンドポイントは既定では有効にならず、厳密に必要な場合にのみ明示的に有効にする必要があります。この場合、ネットワーク セキュリティ グループ (NSG) を適用して、ポート 3342 へのアクセスを信頼できるソース IP アドレスのみに制限することをお勧めします。", + "description": "Managed Instance (SQL MI) パブリック エンドポイントは既定では有効になっていないため、厳密に必要な場合にのみ明示的に有効にする必要があります。この場合、ネットワーク セキュリティ グループ (NSG) を適用して、ポート 3342 へのアクセスを信頼できる送信元 IP アドレスのみに制限することをお勧めします。", "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "高い", "subcategory": "パブリックアクセス", - "text": "Azure SQL マネージド インスタンスのパブリック エンドポイントが必要な場合にアクセスを制限する" + "text": "Azure SQL Managed Instance のパブリック エンドポイントが必要な場合はアクセスを制限する", + "waf": "安全" }, { "category": "特権アクセス", - "description": "Microsoft の担当者と副処理者が実行するほとんどの操作、サポート、およびトラブルシューティングでは、顧客データにアクセスする必要はありません。このようなアクセスが必要なまれな状況では、Microsoft Azure のカスタマー ロックボックスは、顧客が顧客データ アクセス要求を確認して承認または拒否するためのインターフェイスを提供します。 Microsoft が顧客データにアクセスする必要があるサポート シナリオでは、Azure SQL Database はカスタマー ロックボックスをサポートし、顧客データ アクセス要求を確認して承認または拒否するためのインターフェイスを提供します。", + "description": "Microsoft の担当者とサブプロセッサによって実行されるほとんどの操作、サポート、およびトラブルシューティングでは、顧客データにアクセスする必要はありません。このようなアクセスが必要なまれな状況では、Microsoft Azure のカスタマー ロックボックスは、お客様が顧客データ アクセス要求を確認し、承認または拒否するためのインターフェイスを提供します。 Microsoft が顧客データにアクセスする必要があるサポート シナリオでは、Azure SQL Database はカスタマー ロックボックスをサポートし、顧客データ アクセス要求を確認して承認または拒否するためのインターフェイスを提供します。", "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", "severity": "低い", "subcategory": "貸金庫", - "text": "マイクロソフトの担当者による Azure SQL データベース アクセスのカスタマー ロックボックスを確認して有効にする" + "text": "Microsoft の担当者による Azure SQL Database アクセスのカスタマー ロックボックスを確認して有効にする", + "waf": "安全" }, { "category": "特権アクセス", - "description": "最小特権の原則では、ユーザーはタスクを完了するために必要な以上の特権を持つべきではないと規定されています。高い特権を持つデータベースとサーバー ユーザーは、データベースに対して多くの構成およびメンテナンス アクティビティを実行でき、Azure SQL インスタンス内のデータベースを削除することもできます。データベース所有者と特権アカウントを追跡することは、過剰なアクセス許可を持たないようにするために重要です。", + "description": "最小特権の原則では、ユーザーはタスクを完了するために必要以上の特権を持つべきではないとされています。高い特権を持つデータベース ユーザーとサーバー ユーザーは、データベースに対して多くの構成とメンテナンス アクティビティを実行でき、Azure SQL インスタンス内のデータベースを削除することもできます。データベースの所有者と特権アカウントを追跡することは、過剰な権限を持たないために重要です。", "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", "severity": "中程度", "subcategory": "権限", - "text": "ユーザーには、職務を完了するために最低限のアクセスレベルが割り当てられていることを確認します。" + "text": "ユーザーには、職務を完了するために必要最低限のアクセス権が割り当てられていることを確認します", + "waf": "安全" }, { "category": "特権アクセス", - "description": "ID (ユーザーと SPN の両方) は、機能を実行するために必要な最小限のアクセス量にスコープを設定する必要があります。 関連性のないアクセス許可の複数のセットを持つ 1 つの SPN を持つのではなく、スコープが狭い SPN の数を増やす必要があります。たとえば、オンプレミスでホストされている 3 つの外部 Web アプリケーションが Azure SQL Database に対してクエリを実行する場合、すべてのアプリケーションがこれらのアクティビティに同じ SPN を使用するべきではありません。 代わりに、それぞれに独自の厳密なスコープの SPN が必要です。", + "description": "ID (ユーザーと SPN の両方) は、機能を実行するために必要な最小限のアクセスにスコープを設定する必要があります。 1 つの SPN に複数の無関係なアクセス許可のセットを持つのではなく、スコープが狭い SPN の数を増やす必要があります。たとえば、オンプレミスでホストされている 3 つの外部 Web アプリケーションがあり、Azure SQL Database に対してクエリを実行する場合、これらのアクティビティにすべて同じ SPN を使用しないでください。 代わりに、それぞれが独自の厳密にスコープされた SPN を持つ必要があります。", "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", "severity": "低い", "subcategory": "権限", - "text": "個別のアプリケーションには、Azure SQL データベースにアクセスするための最小限のアクセス許可を持つ異なる資格情報が割り当てられるようにする" + "text": "Azure SQL Database にアクセスするための最小限のアクセス許可を持つ異なるアプリケーションに異なる資格情報が割り当てられるようにします", + "waf": "安全" } ], "metadata": { - "name": "Azure SQLDB Security Checklist (Preview)" + "name": "Azure SQLDB Security Checklist (Preview)", + "state": "Preview", + "timestamp": "October 23, 2024" }, "severities": [ { @@ -494,24 +593,49 @@ ], "status": [ { - "description": "このチェックはまだ確認されていません", + "description": "このチェックはまだ見ていません", "name": "未確認" }, { - "description": "このチェックに関連付けられているアクションアイテムがあります", + "description": "このチェックにはアクションアイテムが関連付けられています", "name": "開ける" }, { - "description": "このチェックは検証済みであり、それ以上のアクションアイテムは関連付けられていません", + "description": "このチェックは検証済みであり、これ以上のアクション アイテムは関連付けられていません", "name": "達成" }, { - "description": "推奨事項は理解されていますが、現在の要件では必要ありません", + "description": "推奨事項は理解されているが、現在の要件では必要ではない", "name": "必須ではありません" }, { - "description": "現在のデザインには適用できません", + "description": "現在のデザインには適用されません", "name": "該当なし" } + ], + "waf": [ + { + "name": "確実" + }, + { + "name": "安全" + }, + { + "name": "費用" + }, + { + "name": "オペレーションズ" + }, + { + "name": "パフォーマンス" + } + ], + "yesno": [ + { + "name": "はい" + }, + { + "name": "いいえ" + } ] } \ No newline at end of file diff --git a/checklists/sqldb_checklist.ko.json b/checklists/sqldb_checklist.ko.json index bc997cae..9643f644 100644 --- a/checklists/sqldb_checklist.ko.json +++ b/checklists/sqldb_checklist.ko.json @@ -1,8 +1,7 @@ { - "$schema": "checklist.schema.json", "categories": [ { - "name": "증권 시세 표시기" + "name": "BCDR" }, { "name": "방어자" @@ -37,449 +36,549 @@ ], "items": [ { - "category": "증권 시세 표시기", - "description": "백업이 공격으로부터 보호되는지 확인합니다. 여기에는 기밀성 손실을 방지하기 위한 백업 암호화가 포함되어야 합니다. 정기적인 Azure 서비스 백업의 경우 백업 데이터는 Azure 플랫폼 관리형 키를 사용하여 자동으로 암호화됩니다. 고객 관리형 키를 사용하여 백업을 암호화하도록 선택할 수도 있습니다. 이 경우 키 자격 증명 모음의 이 고객 관리형 키도 백업 범위에 있는지 확인합니다.", + "category": "BCDR", + "description": "백업이 공격으로부터 보호되는지 확인하십시오. 여기에는 기밀성 손실을 방지하기 위한 백업 암호화가 포함되어야 합니다. 일반 Azure 서비스 백업의 경우 백업 데이터는 Azure 플랫폼 관리형 키를 사용하여 자동으로 암호화됩니다. 고객 관리형 키를 사용하여 백업을 암호화하도록 선택할 수도 있습니다. 이 경우 키 자격 증명 모음의 이 고객 관리형 키도 백업 범위에 있는지 확인합니다.", "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", "severity": "보통", "subcategory": "Azure Key Vault", - "text": "암호화를 사용하여 백업 데이터를 보호하고 Azure 키 자격 증명 모음에 안전하게 키를 저장합니다." + "text": "암호화를 통해 백업 데이터를 보호하고 Azure Key Vault에 키를 안전하게 저장", + "waf": "안전" }, { - "category": "증권 시세 표시기", - "description": "Azure SQL 데이터베이스는 SQL Server 기술을 사용하여 매주 전체 백업, 12-24시간마다 차등 백업 및 5-10분마다 트랜잭션 로그 백업을 만듭니다. 기본적으로 SQL 데이터베이스는 쌍을 이루는 지역에 복제되는 지역 중복 저장소 Blob에 데이터를 저장합니다.", + "category": "BCDR", + "description": "Azure SQL Database는 SQL Server 기술을 사용하여 매주 전체 백업, 12-24시간마다 차등 백업, 5-10분마다 트랜잭션 로그 백업을 만듭니다. 기본적으로 SQL Database는 쌍을 이루는 지역에 복제되는 지역 중복 스토리지 Blob에 데이터를 저장합니다.", "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", "severity": "보통", "subcategory": "백업", - "text": "Azure SQL 데이터베이스 자동 백업 구성" + "text": "Azure SQL Database 자동화된 백업 구성", + "waf": "안전" }, { - "category": "증권 시세 표시기", - "description": "기본적으로 SQL 데이터베이스는 쌍을 이루는 지역에 복제되는 지역 중복 저장소 Blob에 데이터를 저장합니다. SQL Database의 경우 데이터베이스를 만들 때 백업 저장소 중복성을 구성하거나 기존 데이터베이스에 대해 업데이트할 수 있습니다. 기존 데이터베이스에 대한 변경 내용은 이후 백업에만 적용됩니다.", + "category": "BCDR", + "description": "기본적으로 SQL Database는 쌍을 이루는 지역에 복제되는 지역 중복 스토리지 Blob에 데이터를 저장합니다. SQL Database의 경우 데이터베이스를 만들 때 백업 스토리지 중복성을 구성하거나 기존 데이터베이스에 대해 업데이트할 수 있습니다. 기존 데이터베이스에 대한 변경 사항은 향후 백업에만 적용됩니다.", "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", "severity": "낮다", "subcategory": "백업", - "text": "지역 중복 백업 스토리지를 사용하도록 설정하여 단일 지역 오류 및 데이터 손실로부터 보호" + "text": "지역 중복 백업 스토리지를 사용하여 단일 지역 오류 및 데이터 손실로부터 보호Enable geo-redundant backup storage to protect against single region failure and data loss", + "waf": "안전" }, { "category": "코드", - "description": "악성 코드는 잠재적으로 보안 제어를 우회할 수 있습니다. 사용자 지정 코드를 프로덕션에 배포하기 전에 배포 중인 코드를 검토하는 것이 중요합니다. 소스 제어를 지원하는 Azure 데이터 스튜디오와 같은 데이터베이스 도구를 사용합니다. 코드 분석, 취약성 및 자격 증명 검사를 위한 도구와 논리를 구현합니다.", + "description": "악성 코드는 잠재적으로 보안 제어를 우회할 수 있습니다. 사용자 지정 코드를 프로덕션에 배포하기 전에 배포되는 내용을 검토하는 것이 중요합니다. 소스 제어를 지원하는 Azure Data Studio와 같은 데이터베이스 도구를 사용합니다. 코드 분석, 취약성 및 자격 증명 검사를 위한 도구와 논리를 구현합니다.", "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "보통", "subcategory": "소스 제어 및 코드 검토", - "text": "소스 제어 시스템을 사용하여 Azure SQLDB 데이터베이스 내에 배포된 애플리케이션 코드를 저장, 유지 관리 및 검토합니다." + "text": "소스 제어 시스템을 사용하여 Azure SQLDB 데이터베이스 내에 배포된 응용 프로그램 코드를 저장, 유지 관리 및 검토합니다.", + "waf": "안전" }, { "category": "데이터 검색 및 분류", - "description": "분류 요구 사항의 경우 Purview가 선호되는 옵션입니다. Purview가 옵션이 아닌 경우에만 SQL 데이터 검색 및 분류를 사용합니다. 중요한 데이터가 포함될 가능성이 있는 열을 검색합니다. 민감한 데이터로 간주되는 것은 고객, 규정 준수 규정 등에 따라 크게 달라지며 해당 데이터를 담당하는 사용자가 평가해야 합니다. 열을 분류하여 고급 민감도 기반 감사 및 보호 시나리오를 사용합니다. 자동화된 검색 결과를 검토하고 필요한 경우 분류를 완료합니다.", + "description": "분류 요구 사항의 경우 Purview가 선호되는 옵션입니다. Purview가 옵션이 아닌 경우에만 SQL 데이터 검색 & 분류를 사용합니다. 중요한 데이터를 포함할 수 있는 열을 검색합니다. 민감한 데이터로 간주되는 것은 고객, 규정 준수 규정 등에 따라 크게 달라지며 해당 데이터를 담당하는 사용자가 평가해야 합니다. 고급 민감도 기반 감사 및 보호 시나리오를 사용하도록 열을 분류합니다. 자동화된 검색의 결과를 검토하고 필요한 경우 분류를 완료합니다.", "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", "severity": "낮다", "subcategory": "데이터 검색 및 분류", - "text": "중요한 데이터를 보호하기 위한 데이터 검색 및 분류 계획 및 구성" + "text": "민감한 데이터를 보호하기 위한 Data Discovery & Classification 계획 및 구성", + "waf": "안전" }, { "category": "데이터 마스킹", - "description": "이 기능은 열 암호화가 옵션이 아니며 데이터 형식 및 형식을 보존해야 하는 특정 요구 사항이 있는 경우에만 사용하는 것이 좋습니다. 동적 데이터 마스킹은 권한이 없는 사용자에게 마스킹하여 중요한 데이터 노출을 제한합니다. 동적 데이터 마스킹은 고객이 애플리케이션 계층에 미치는 영향을 최소화하면서 표시할 중요한 데이터의 양을 지정할 수 있도록 하여 중요한 데이터에 대한 무단 액세스를 방지하는 데 도움이 됩니다.", + "description": "이 기능은 열 암호화가 옵션이 아니며 데이터 형식 및 형식을 보존하기 위한 특정 요구 사항이 있는 경우에만 사용하는 것이 좋습니다. 동적 데이터 마스킹은 권한이 없는 사용자에게 마스킹하여 민감한 데이터 노출을 제한합니다. 동적 데이터 마스킹은 고객이 애플리케이션 계층에 미치는 영향을 최소화하면서 노출할 민감한 데이터의 양을 지정할 수 있도록 하여 민감한 데이터에 대한 무단 액세스를 방지하는 데 도움이 됩니다.", "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", "severity": "낮다", "subcategory": "데이터 마스킹", - "text": "데이터 마스킹을 사용하여 암호화가 불가능한 경우 관리자가 아닌 무단 사용자의 데이터 액세스 방지" + "text": "암호화가 불가능한 경우 Data Masking을 사용하여 관리자가 아닌 사용자의 무단 데이터 액세스를 방지합니다.", + "waf": "안전" }, { "category": "방어자", - "description": "SQL ATP(고급 위협 감지)는 SQL 삽입 공격 및 비정상적인 동작 패턴과 같은 데이터베이스에서 잠재적인 취약성 및 비정상적인 활동을 검색하는 보안 계층을 제공합니다. 잠재적 위협이 감지되면 위협 감지는 특정 위협에 대한 명확한 조사 및 수정 단계를 포함하는 전자 메일 및 클라우드용 Microsoft Defender에서 실행 가능한 실시간 경고를 보냅니다.", + "description": "SQL ATP(Advanced Threat Detection)는 SQL 삽입 공격 및 비정상적인 동작 패턴과 같은 데이터베이스의 잠재적 취약성 및 비정상적인 활동을 감지하는 보안 계층을 제공합니다. 잠재적인 위협이 감지되면 위협 탐지는 특정 위협에 대한 명확한 조사 및 수정 단계를 포함하는 전자 메일 및 클라우드용 Microsoft Defender 실행 가능한 실시간 경고를 보냅니다.", "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "높다", - "subcategory": "지능형 위협 보호", - "text": "ATP(고급 위협 보호) 구성 검토 및 완료" + "subcategory": "Advanced Threat Protection", + "text": "ATP(Advanced Threat Protection) 구성 검토 및 완료", + "waf": "안전" }, { "category": "방어자", - "description": "구독 수준에서 Azure SQL용 Microsoft Defender를 사용하도록 설정하여 기존 및 미래의 모든 서버와 데이터베이스를 자동으로 온보딩하고 보호합니다. 구독 수준에서 사용하도록 설정하면 Azure SQL 데이터베이스 및 Azure SQL 관리되는 인스턴스의 모든 데이터베이스가 보호됩니다. 그런 다음 원하는 경우 개별적으로 비활성화할 수 있습니다. 보호되는 데이터베이스를 수동으로 관리하려면 구독 수준에서 사용하지 않도록 설정하고 보호할 각 데이터베이스를 사용하도록 설정합니다.", + "description": "구독 수준에서 Microsoft Defender for Azure SQL을 사용하도록 설정하여 기존 및 미래의 모든 서버와 데이터베이스를 자동으로 등록하고 보호합니다. 구독 수준에서 사용하도록 설정하면 Azure SQL Database 및 Azure SQL Managed Instance의 모든 데이터베이스가 보호됩니다. 그런 다음 원하는 경우 개별적으로 비활성화할 수 있습니다. 보호할 데이터베이스를 수동으로 관리하려면 구독 수준에서 사용하지 않도록 설정하고 보호하려는 각 데이터베이스를 사용하도록 설정합니다.", "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", "severity": "높다", - "subcategory": "Defender for Azure SQL", - "text": "Enable Microsoft Defender for Azure SQL" + "subcategory": "Azure SQL용 Defender", + "text": "Azure SQL용 Microsoft Defender 사용", + "waf": "안전" }, { "category": "방어자", - "description": "Azure SQL ATP용 Microsoft Defender는 데이터베이스에 액세스하거나 악용하려는 비정상적이고 잠재적으로 유해한 시도를 나타내는 비정상적인 활동을 검색합니다. 경고를 구성하고 생성할 수 있으며 콘솔용 Defender에 보고됩니다.", + "description": "Azure SQL ATP용 Microsoft Defender는 데이터베이스에 액세스하거나 악용하려는 비정상적이고 잠재적으로 해로운 시도를 나타내는 비정상적인 활동을 감지합니다. 경고를 구성하고 생성할 수 있으며 콘솔용 Defender에 보고됩니다.", "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "높다", - "subcategory": "Defender for Azure SQL", - "text": "Azure SQL 경고에 대한 Microsoft Defender에 즉시 대응하기 위한 보안 대응 계획 준비" + "subcategory": "Azure SQL용 Defender", + "text": "Microsoft Defender for Azure SQL 경고에 신속하게 대응하기 위한 보안 대응 계획 준비", + "waf": "안전" }, { "category": "방어자", "description": "Azure SQLDB 취약성 평가는 보안 상태에 대한 가시성을 제공하는 서비스입니다. 취약성 평가에는 보안 문제를 해결하고 데이터베이스 보안을 강화하기 위한 실행 가능한 단계가 포함됩니다. 변경 사항을 추적하기 어려운 동적 데이터베이스 환경을 모니터링하고 SQL 보안 상태를 개선하는 데 도움이 될 수 있습니다.", "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", "severity": "높다", "subcategory": "취약성 평가", - "text": "취약성 평가(VA) 결과 구성 및 권장 사항 검토" + "text": "VA(Vulnerability Assessment) 결과 구성 및 권장 사항 검토", + "waf": "안전" }, { "category": "방어자", - "description": "Microsoft Defender for Cloud는 Azure SQL Database에 대한 취약성 평가를 제공합니다. 취약성 평가는 데이터베이스에서 소프트웨어 취약성을 검색하고 결과 목록을 제공합니다. 결과를 사용하여 소프트웨어 취약성을 수정하고 결과를 사용하지 않도록 설정할 수 있습니다.", + "description": "클라우드용 Microsoft Defender는 Azure SQL Database에 대한 취약성 평가를 제공합니다. 취약성 평가는 데이터베이스에서 소프트웨어 취약성을 검사하고 결과 목록을 제공합니다. 결과를 사용하여 소프트웨어 취약성을 수정하고 결과를 비활성화할 수 있습니다.", "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", "severity": "높다", "subcategory": "취약성 평가", - "text": "취약성 평가(VA) 결과 및 권장 사항을 정기적으로 검토하고 수정 계획을 준비합니다." + "text": "취약성 평가(VA) 결과 및 권장 사항을 정기적으로 검토하고 수정 계획을 준비합니다.", + "waf": "안전" }, { "category": "암호화", - "description": "보안 엔클레이브를 사용한 상시 암호화는 현재 위치 암호화 및 보다 풍부한 기밀 쿼리를 활성화하여 상시 암호화의 기밀 컴퓨팅 기능을 확장합니다. 보안 엔클레이브로 항상 암호화는 서버 측의 보안 엔클레이브 내에서 일반 텍스트 데이터에 대한 일부 계산을 허용하여 이러한 제한 사항을 해결합니다. 이 기능은 관리자 액세스를 제한해야 하고 쿼리가 암호화된 열의 동일성 일치 이상을 지원해야 하는 경우에 사용하는 것이 좋습니다.", + "description": "Secure Enclaves를 사용한 Always Encrypted는 현재 위치 암호화 및 더 풍부한 기밀 쿼리를 사용하도록 설정하여 Always Encrypted의 기밀 컴퓨팅 기능을 확장합니다. Secure Enclaves를 사용한 Always Encrypted는 서버 쪽의 보안 Enclave 내에서 일반 텍스트 데이터에 대한 일부 계산을 허용하여 이러한 제한 사항을 해결합니다. 이 기능은 관리자 액세스를 제한해야 하고 쿼리가 암호화된 열의 동등성 일치 이상을 지원해야 하는 경우에 사용하는 것이 좋습니다.", "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", "severity": "보통", - "subcategory": "상시 암호화", - "text": "관리자로부터 중요한 PII 데이터를 보호하는 것이 핵심 요구 사항이지만 열 암호화 제한을 허용할 수 없는 경우 보안 엔클레이브를 사용하여 상시 암호화 채택을 고려하십시오." + "subcategory": "상시 암호화(Always Encrypted)", + "text": "관리 사용자로부터 중요한 PII 데이터를 보호하는 것이 주요 요구 사항이지만 열 암호화 제한을 허용할 수 없는 경우 Secure Enclave를 사용한 Always Encrypted를 채택하는 것이 좋습니다", + "waf": "안전" }, { "category": "암호화", - "description": "Azure SQL 데이터베이스에서는 Transact-SQL을 사용하여 데이터 열에 대칭 암호화를 적용할 수 있습니다. 이 방법을 열 암호화라고 하는데, 이는 서로 다른 암호화 키를 사용하여 특정 열을 암호화하는 데 사용할 수 있기 때문입니다. 이렇게 하면 페이지의 데이터를 암호화하는 TDE보다 더 세분화된 암호화 기능이 제공됩니다. 상시 암호화를 사용하여 메모리/사용 중인 경우에도 Azure SQL 데이터베이스 또는 SQL 관리되는 인스턴스에서 중요한 데이터가 일반 텍스트로 노출되지 않도록 합니다. 상시 암호화는 DBA(데이터베이스 관리자) 및 클라우드 관리자(또는 권한이 높지만 권한이 없는 사용자를 가장할 수 있는 악의적인 행위자)로부터 데이터를 보호하고 데이터에 액세스할 수 있는 사용자를 더 잘 제어할 수 있도록 합니다.", + "description": "Azure SQL Database를 사용하면 Transact-SQL을 사용하여 데이터 열에 대칭 암호화를 적용할 수 있습니다. 이 방법을 열 암호화라고 하는데, 이 방법을 사용하여 다른 암호화 키를 가진 특정 열을 암호화할 수 있기 때문입니다. 이렇게 하면 페이지의 데이터를 암호화하는 TDE보다 더 세분화된 암호화 기능이 제공됩니다. Always Encrypted를 사용하여 메모리/사용 중에도 중요한 데이터가 Azure SQL Database 또는 SQL Managed Instance에서 일반 텍스트로 노출되지 않도록 합니다. Always Encrypted는 DBA(데이터베이스 관리자) 및 클라우드 관리자(또는 권한이 높지만 권한이 없는 사용자를 가장할 수 있는 악의적인 행위자)로부터 데이터를 보호하고 데이터에 액세스할 수 있는 사용자를 더 많이 제어할 수 있도록 합니다.", "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", "severity": "낮다", - "subcategory": "열 암호화", - "text": "특정 테이블 열에서 관리자가 아닌 사용자로부터 중요한 PII 데이터를 보호하려면 열 암호화를 사용하는 것이 좋습니다." + "subcategory": "컬럼 암호화(Column Encryption)", + "text": "특정 테이블 열에서 관리자가 아닌 사용자로부터 중요한 PII 데이터를 보호하려면 열 암호화를 사용하는 것이 좋습니다", + "waf": "안전" }, { "category": "암호화", - "description": "기본적으로 사용하도록 설정된 TDE(투명한 데이터 암호화)는 응용 프로그램을 변경할 필요 없이 데이터베이스, 연결된 백업 및 '미사용 상태' 트랜잭션 로그 파일의 실시간 암호화 및 암호 해독을 수행하여 정보 유출로부터 데이터베이스 파일을 보호하는 데 도움이 됩니다.", + "description": "기본적으로 사용하도록 설정된 TDE(투명한 데이터 암호화)는 응용 프로그램을 변경할 필요 없이 데이터베이스, 연결된 백업 및 트랜잭션 로그 파일의 '미사용' 실시간 암호화 및 암호 해독을 수행하여 정보 공개로부터 데이터베이스 파일을 보호하는 데 도움이 됩니다.", "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "높다", "subcategory": "투명한 데이터 암호화", - "text": "TDE(투명한 데이터 암호화)가 사용하도록 설정된 상태로 유지되는지 확인" + "text": "TDE(투명한 데이터 암호화)가 활성화된 상태로 유지되는지 확인합니다.", + "waf": "안전" }, { "category": "암호화", - "description": "조직 내에서 키 및 데이터 관리에서 업무를 분리해야 하는 경우 Azure SQLDB에 대한 TDE(투명한 데이터 암호화)에 CMK(고객 관리형 키)를 활용하고 Azure 키 자격 증명 모음을 사용하여 저장합니다(검사 목록 참조). 관리 서비스 키로 충족할 수 없는 엄격한 보안 요구 사항이 있는 경우 이 기능을 활용합니다.", + "description": "조직 내에서 키와 데이터를 관리하는 업무를 분리해야 하는 경우 Azure SQLDB에 대한 TDE(투명한 데이터 암호화)를 위해 CMK(고객 관리형 키)를 활용하고 Azure Key Vault를 사용하여 저장합니다(검사 목록 참조). 관리 서비스 키로 충족할 수 없는 엄격한 보안 요구 사항이 있는 경우 이 기능을 활용하십시오.", "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", "severity": "보통", "subcategory": "투명한 데이터 암호화", - "text": "TDE 보호에 대한 투명성과 세분화된 제어가 필요한 경우 AKV(Azure 키 자격 증명 모음)에서 CMK(고객 관리형 키)를 사용합니다." + "text": "TDE 보호에 대한 투명성을 높이고 세부적으로 제어해야 하는 경우 AKV(Azure Key Vault)에서 CMK(고객 관리형 키)를 사용합니다.", + "waf": "안전" }, { "category": "암호화", "description": "최소 TLS(전송 계층 보안) 버전 설정을 통해 고객은 SQL 데이터베이스에서 사용하는 TLS 버전을 선택할 수 있습니다. Azure Portal, Azure PowerShell 및 Azure CLI를 사용하여 최소 TLS 버전을 변경할 수 있습니다.", "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", "severity": "높다", "subcategory": "전송 계층 보안", - "text": "최소 TLS 버전을 사용 가능한 최신 버전으로 적용" + "text": "최소 TLS 버전을 사용 가능한 최신 버전으로 적용", + "waf": "안전" }, { "category": "신원", - "description": "중앙 집중식 ID 관리를 위해 Azure AD(Azure Active Directory) 인증을 사용합니다. 실제로 필요한 경우에만 SQL 인증을 사용하고 예외로 문서화하십시오.", + "description": "중앙 집중식 ID 관리를 위해 Azure AD(Azure Active Directory) 인증을 사용합니다. 실제로 필요한 경우에만 SQL 인증을 사용하고 예외로 문서화합니다.", "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", "severity": "보통", - "subcategory": "Azure Active Directory", - "text": "Azure SQL 데이터베이스에 대한 연결을 위해 Azure AD 인증 활용" + "subcategory": "Azure 액티브 디렉토리", + "text": "Azure SQL Database에 대한 연결을 위해 Azure AD 인증 활용", + "waf": "안전" }, { "category": "신원", - "description": "Azure AD 그룹을 사용하면 권한 관리가 간소화되고 그룹 소유자와 리소스 소유자 모두 그룹에서 구성원을 추가/제거할 수 있습니다. 각 논리 서버에 대해 Azure AD 관리자에 대한 별도의 그룹을 만듭니다. Azure AD 감사 활동 보고서를 사용하여 Azure AD 그룹 멤버 자격 변경을 모니터링합니다.", + "description": "Azure AD 그룹을 사용하면 권한 관리가 간소화되고 그룹 소유자와 리소스 소유자 모두 그룹에서 구성원을 추가/제거할 수 있습니다. 각 논리 서버에 대해 Azure AD 관리자를 위한 별도의 그룹을 만듭니다. Azure AD 감사 활동 보고서를 사용하여 Azure AD 그룹 멤버 자격 변경 사항을 모니터링합니다.", "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", "severity": "보통", - "subcategory": "Azure Active Directory", - "text": "각 Azure SQL 데이터베이스 논리 서버에 대해 두 개의 관리자 계정이 있는 별도의 Azure AD 그룹 만들기" + "subcategory": "Azure 액티브 디렉토리", + "text": "각 Azure SQL Database 논리 서버에 대해 두 개의 관리자 계정이 있는 별도의 Azure AD 그룹을 만듭니다.", + "waf": "안전" }, { "category": "신원", - "description": "최소 권한이 할당된 함수 전용인 고유한 시스템 및 사용자 할당 관리 ID가 Azure 서비스 및 애플리케이션에서 Azure SQLDB 데이터베이스로의 통신에 사용되는지 확인합니다.", + "description": "최소한의 권한이 할당된 함수 전용의 고유한 시스템 및 사용자 할당 관리 ID가 Azure 서비스 및 애플리케이션에서 Azure SQLDB 데이터베이스로의 통신에 사용되는지 확인합니다.", "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", "severity": "보통", - "subcategory": "Azure Active Directory", - "text": "응용 프로그램에 대한 암호 기반 인증 사용 최소화" + "subcategory": "Azure 액티브 디렉토리", + "text": "응용 프로그램에 대한 암호 기반 인증 사용 최소화Minimize the use of password-based authentication for applications", + "waf": "안전" }, { "category": "신원", - "description": "시스템 또는 사용자 할당 관리 ID를 사용하면 Azure SQLDB가 코드에 자격 증명을 저장하지 않고도 다른 클라우드 서비스(예: Azure 키 자격 증명 모음)에 인증할 수 있습니다. 사용하도록 설정되면 Azure 역할 기반 액세스 제어를 통해 특정 Azure SQLDB 인스턴스에 필요한 모든 권한을 부여할 수 있습니다. 엄격하게 필요하지 않은 경우 여러 서비스에서 사용자 할당 관리 ID를 공유하지 마세요.", + "description": "시스템 또는 사용자 할당 관리 ID를 사용하면 Azure SQLDB가 코드에 자격 증명을 저장하지 않고도 다른 클라우드 서비스(예: Azure Key Vault)에 인증할 수 있습니다. 사용하도록 설정하면 Azure 역할 기반 액세스 제어를 통해 특정 Azure SQLDB 인스턴스에 필요한 모든 권한을 부여할 수 있습니다. 반드시 필요하지 않은 경우 여러 서비스에서 사용자가 할당한 관리 ID를 공유하지 마세요.", "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "severity": "낮다", "subcategory": "관리 ID", - "text": "Azure SQL 데이터베이스에 아웃바운드 리소스 액세스를 위한 관리 ID 할당" + "text": "아웃바운드 리소스 액세스를 위한 관리 ID를 Azure SQL Database 할당Assign Azure SQL Database a managed identity for outbound resource access", + "waf": "안전" }, { "category": "신원", - "description": "암호 사용을 제거하는 Azure AD 통합 인증을 사용합니다. 암호 기반 인증 방법은 더 약한 인증 형식입니다. 자격 증명이 손상되거나 실수로 제공될 수 있습니다. Windows 자격 증명을 사용한 싱글 사인온 인증을 사용합니다. 온-프레미스 AD 도메인을 Azure AD와 페더레이션하고 Windows 통합 인증을 사용합니다(Azure AD를 사용하여 도메인에 가입된 컴퓨터의 경우).", + "description": "암호를 사용하지 않는 Azure AD 통합 인증을 사용합니다. 암호 기반 인증 방법은 더 약한 형태의 인증입니다. 자격 증명이 손상되거나 실수로 제공될 수 있습니다. Windows 자격 증명을 사용하여 Single Sign-On 인증을 사용합니다. 온-프레미스 AD 도메인을 Azure AD와 페더레이션하고 Windows 통합 인증을 사용합니다(Azure AD를 사용하는 도메인 가입 컴퓨터의 경우).", "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", "severity": "보통", "subcategory": "암호", - "text": "사용자에 대한 암호 기반 인증 사용 최소화" + "text": "사용자에 대한 암호 기반 인증 사용 최소화", + "waf": "안전" }, { "category": "원장", - "description": "데이터베이스 원장에 있는 최신 블록의 해시를 데이터베이스 다이제스트라고 합니다. 블록이 생성된 시점에 데이터베이스에 있는 모든 원장 테이블의 상태를 나타냅니다. 데이터베이스 다이제스트 생성은 최근에 추가된 블록의 해시만 계산하기 때문에 효율적입니다. Azure 기밀 원장은 지원되는 저장소 중 하나이며 데이터베이스 다이제스트의 자동 생성 및 저장을 지원하고 사용할 수 있습니다. Azure Ledger는 블록체인 원장 증명 및 기밀 하드웨어 엔클레이브와 같은 고급 보안 기능을 제공합니다. 고급 보안 기능이 필요한 경우에만 사용하고, 그렇지 않으면 Azure 저장소로 되돌립니다.", + "description": "데이터베이스 원장에 있는 최신 블록의 해시를 데이터베이스 다이제스트라고 합니다. 블록이 생성된 시점에 데이터베이스에 있는 모든 원장 테이블의 상태를 나타냅니다. 데이터베이스 다이제스트를 생성하는 것은 최근에 추가된 블록의 해시만 계산하기 때문에 효율적입니다. Azure Confidential Ledger는 지원되는 저장소 중 하나이며, 데이터베이스 다이제스트의 자동 생성 및 저장을 지원하고 사용할 수 있습니다. Azure Ledger는 블록체인 원장 증명 및 기밀 하드웨어 엔클레이브와 같은 고급 보안 기능을 제공합니다. 고급 보안 기능이 필요한 경우에만 사용하고, 그렇지 않으면 Azure Storage로 되돌립니다.", "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", "severity": "보통", "subcategory": "데이터베이스 다이제스트", - "text": "Azure 기밀 원장을 사용하여 고급 보안 기능이 필요한 경우에만 데이터베이스 다이제스트 저장" + "text": "Azure Confidential Ledger를 사용하여 고급 보안 기능이 필요한 경우에만 데이터베이스 다이제스트를 저장합니다.", + "waf": "안전" }, { "category": "원장", - "description": "데이터베이스 원장에 있는 최신 블록의 해시를 데이터베이스 다이제스트라고 합니다. 블록이 생성된 시점에 데이터베이스에 있는 모든 원장 테이블의 상태를 나타냅니다. 데이터베이스 다이제스트 생성은 최근에 추가된 블록의 해시만 계산하기 때문에 효율적입니다. 변경할 수 없는 저장소 기능이 있는 Azure Blob 저장소를 사용할 수 있으며 데이터베이스 다이제스트의 자동 생성 및 저장소를 지원합니다. 다이제스트 파일의 변조를 방지하려면 컨테이너에 대한 보존 정책을 구성하고 잠급니다.", + "description": "데이터베이스 원장에 있는 최신 블록의 해시를 데이터베이스 다이제스트라고 합니다. 블록이 생성된 시점에 데이터베이스에 있는 모든 원장 테이블의 상태를 나타냅니다. 데이터베이스 다이제스트를 생성하는 것은 최근에 추가된 블록의 해시만 계산하기 때문에 효율적입니다. 변경할 수 없는 스토리지 기능이 있는 Azure Blob Storage를 사용할 수 있으며 데이터베이스 다이제스트의 자동 생성 및 스토리지를 지원합니다. 다이제스트 파일의 변조를 방지하려면 컨테이너에 대한 보존 정책을 구성하고 잠급니다.", "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", "severity": "보통", "subcategory": "데이터베이스 다이제스트", - "text": "Azure 저장소 계정을 사용하여 데이터베이스 다이제스트를 저장하는 경우 보안이 올바르게 구성되었는지 확인합니다." + "text": "Azure Storage 계정을 사용하여 데이터베이스 다이제스트를 저장하는 경우 보안이 제대로 구성되었는지 확인합니다", + "waf": "안전" }, { "category": "원장", - "description": "Ledger는 원장 테이블의 데이터에 대한 데이터 변조의 증거를 제공하는 정방향 무결성이라는 데이터 무결성 형식을 제공합니다. 데이터베이스 검증 프로세스는 이전에 생성된 하나 이상의 데이터베이스 다이제스트를 입력으로 사용합니다. 그런 다음 원장 테이블의 현재 상태를 기반으로 데이터베이스 원장에 저장된 해시를 다시 계산합니다. 계산된 해시가 입력 다이제스트와 일치하지 않으면 확인이 실패합니다. 이 오류는 데이터가 변조되었음을 나타냅니다. 확인 프로세스는 감지된 모든 불일치를 보고합니다.", + "description": "원장은 순방향 무결성이라는 데이터 무결성의 한 형태를 제공하며, 이는 원장 테이블의 데이터에 대한 데이터 변조의 증거를 제공합니다. 데이터베이스 확인 프로세스는 이전에 생성된 하나 이상의 데이터베이스 다이제스트를 입력으로 사용합니다. 그런 다음 원장 테이블의 현재 상태를 기반으로 데이터베이스 원장에 저장된 해시를 다시 계산합니다. 계산된 해시가 입력 다이제스트와 일치하지 않으면 확인이 실패합니다. 실패는 데이터가 변조되었음을 나타냅니다. 확인 프로세스는 감지된 모든 불일치를 보고합니다.", "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", "severity": "보통", "subcategory": "무결성", - "text": "데이터 무결성을 확인하기 위해 Ledger 확인 프로세스를 정기적으로 예약합니다." + "text": "원장 확인 프로세스를 정기적으로 예약하여 데이터 무결성을 확인합니다.", + "waf": "안전" }, { "category": "원장", - "description": "Ledger 기능은 데이터베이스에서 변조 증거 기능을 제공합니다. 감사자 또는 다른 비즈니스 당사자와 같은 다른 당사자에게 데이터가 변조되지 않았음을 암호로 증명할 수 있습니다. Ledger는 데이터베이스 관리자(DBA), 시스템 관리자, 클라우드 관리자를 포함한 모든 공격자 또는 권한이 높은 사용자로부터 데이터를 보호하는 데 도움이 됩니다.", + "description": "원장 기능은 데이터베이스에서 변조 증거 기능을 제공합니다. 감사자 또는 다른 비즈니스 당사자와 같은 다른 당사자에게 데이터가 변조되지 않았음을 암호화 방식으로 증명할 수 있습니다. Ledger는 데이터베이스 관리자(DBA), 시스템 관리자, 클라우드 관리자 등 공격자 또는 권한이 높은 사용자로부터 데이터를 보호하는 데 도움이 됩니다.", "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", "severity": "보통", "subcategory": "원장", - "text": "데이터 무결성에 대한 암호화 증명이 중요한 요구 사항인 경우 Ledger 기능을 고려해야 합니다." + "text": "데이터 무결성의 암호화 증명이 중요한 요구 사항인 경우 원장 기능을 고려해야 합니다", + "waf": "안전" }, { "category": "원장", - "description": "변조 유형에 따라 데이터 손실 없이 원장을 복구할 수 있는 경우가 있습니다. --추가 정보-- 열에 포함된 문서에서는 다양한 시나리오와 복구 기술에 대해 설명합니다.", + "description": "변조의 유형에 따라 데이터 손실 없이 원장을 수리할 수 있는 경우가 있습니다. --More Info-- 열에 포함된 문서에는 다양한 시나리오와 복구 기술이 설명되어 있습니다.", "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", "severity": "보통", "subcategory": "복구", - "text": "변조 이벤트 후 데이터베이스를 조사하고 복구하기 위한 대응 계획 준비" + "text": "변조 이벤트 후 데이터베이스를 조사하고 복구하기 위한 대응 계획 준비Prepare a response plan to investigate and repair a database after a tampering event", + "waf": "안전" }, { "category": "로깅", - "description": "Azure SQL 데이터베이스 감사는 데이터베이스 이벤트를 추적하여 Azure 저장소 계정의 감사 로그에 씁니다. 감사는 데이터베이스 작업을 이해하고 비즈니스 문제 또는 의심되는 보안 위반을 나타낼 수 있는 불일치 및 변칙에 대한 통찰력을 얻는 데 도움이 될 뿐만 아니라 규정 준수를 충족하는 데 도움이 됩니다. 기본적으로 감사 정책에는 데이터베이스에 대한 모든 작업(쿼리, 저장 프로시저, 성공 및 실패한 로그인)이 포함되며, 이로 인해 많은 양의 감사 로그가 발생할 수 있습니다. 고객은 PowerShell을 사용하여 다양한 유형의 작업 및 작업 그룹에 대한 감사를 구성하는 것이 좋습니다.", + "description": "Azure SQL Database 감사는 데이터베이스 이벤트를 추적하여 Azure Storage 계정의 감사 로그에 기록합니다. 감사는 데이터베이스 활동을 이해하고, 비즈니스 문제 또는 의심되는 보안 위반을 나타낼 수 있는 불일치 및 이상 징후에 대한 통찰력을 얻을 뿐만 아니라 규정 준수를 충족하는 데 도움이 됩니다. 기본적으로 감사 정책에는 데이터베이스에 대한 모든 작업(쿼리, 저장 프로시저, 로그인 성공 및 실패)이 포함되며, 이로 인해 감사 로그의 양이 많아질 수 있습니다. 고객은 PowerShell을 사용하여 다양한 유형의 작업 및 작업 그룹에 대한 감사를 구성하는 것이 좋습니다.", "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "보통", "subcategory": "감사", - "text": "Azure SQL 데이터베이스 감사가 서버 수준에서 사용하도록 설정되어 있는지 확인" + "text": "서버 수준에서 Azure SQL Database 감사가 사용하도록 설정되어 있는지 확인합니다.", + "waf": "안전" }, { "category": "로깅", - "description": "Azure SQL 데이터베이스 감사 로그는 외부 저장소 계정, 로그 분석 작업 영역 또는 이벤트 허브에 쓸 수 있습니다. 백업 및 보안 구성을 사용하여 대상 저장소를 보호해야 합니다. Azure SQL 데이터베이스 관리 ID를 사용하여 스토리지에 액세스하고 명시적 보존 기간을 설정합니다. 관리자에게 감사 로그 저장소에 대한 권한을 부여하지 마십시오. --Microsoft 지원 작업의 감사 사용에 다른 대상 저장소를 사용합니다--. ", + "description": "Azure SQL Database 감사 로그는 외부 스토리지 계정, Log Analytics 작업 영역 또는 이벤트 허브에 기록할 수 있습니다. 백업 및 보안 구성을 사용하여 대상 저장소를 보호해야 합니다. Azure SQL Database 관리 ID를 사용하여 스토리지에 액세스하고 명시적 보존 기간을 설정합니다. 관리자에게 감사 로그 리포지토리에 대한 권한을 부여하지 마십시오. --Microsoft 지원 작업 감사를 사용하도록 설정하기 위해 다른 대상 저장소를 사용합니다--. ", "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "낮다", "subcategory": "감사", - "text": "Azure SQL 데이터베이스 감사 로그가 선택한 리포지토리 유형에서 백업 및 보호되는지 확인" + "text": "Azure SQL Database 감사 로그가 선택한 리포지토리 유형에서 백업되고 보호되는지 확인합니다.", + "waf": "안전" }, { "category": "로깅", - "description": "Azure 모니터 활동 로그는 구독 수준 이벤트에 대한 인사이트를 제공하는 Azure의 플랫폼 로그입니다. 활동 로그에는 리소스가 수정된 시기와 같은 정보가 포함됩니다. 이 활동 로그를 Azure SQL 데이터베이스 감사 로그(저장소 계정, 로그 분석 작업 영역, 이벤트 허브)와 동일한 외부 저장소 리포지토리로 보내는 것이 좋습니다.", + "description": "Azure Monitor 활동 로그는 구독 수준 이벤트에 대한 인사이트를 제공하는 Azure의 플랫폼 로그입니다. 활동 로그에는 리소스가 수정된 시기와 같은 정보가 포함됩니다. 이 활동 로그를 Azure SQL Database 감사 로그와 동일한 외부 스토리지 리포지토리(스토리지 계정, Log Analytics 작업 영역, 이벤트 허브)로 보내는 것이 좋습니다.", "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "보통", "subcategory": "감사", - "text": "Azure SQL 데이터베이스 활동 로그가 수집되고 감사 로그와 통합되었는지 확인" + "text": "Azure SQL Database 활동 로그가 수집되고 감사 로그와 통합되는지 확인합니다.", + "waf": "안전" }, { "category": "로깅", - "description": "Azure SQL의 모든 로그를 SIEM(보안 정보 및 이벤트 관리) 및 SOAR(보안 오케스트레이션 자동화 및 응답)로 전달합니다. 잠재적인 위협 및 변칙에 대해 다양한 유형의 Azure 자산을 모니터링하고 있는지 확인합니다. 분석가가 분류해야 하는 가양성을 줄이기 위해 고품질 경고를 받는 데 집중합니다. 경고는 로그 데이터, 에이전트 또는 기타 데이터에서 가져올 수 있습니다.", + "description": "Azure SQL의 모든 로그를 SIEM(보안 정보 및 이벤트 관리) 및 SOAR(보안 오케스트레이션 자동화 및 응답)로 전달합니다. 잠재적인 위협 및 변칙에 대해 다양한 유형의 Azure 자산을 모니터링하고 있는지 확인합니다. 분석가가 분류할 수 있는 오탐을 줄이기 위해 고품질 경고를 받는 데 집중합니다. 경고는 로그 데이터, 에이전트 또는 기타 데이터에서 제공될 수 있습니다.", "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "보통", - "subcategory": "SIEM/SOAR", - "text": "Azure SQL 데이터베이스 감사 로그가 조직에 제공되는지 확인 SIEM/SOAR" + "subcategory": "SIEM/소이어", + "text": "Azure SQL Database 감사 로그가 조직 SIEM/SOAR에 제공되고 있는지 확인합니다.", + "waf": "안전" }, { "category": "로깅", - "description": "Azure SQL의 모든 로그를 SIEM(보안 정보 및 이벤트 관리) 및 SOAR(보안 오케스트레이션 자동화 및 대응)로 전달하여 사용자 지정 위협 검색을 설정하는 데 사용할 수 있습니다. 잠재적인 위협 및 변칙에 대해 다양한 유형의 Azure 자산을 모니터링하고 있는지 확인합니다. 분석가가 분류해야 하는 가양성을 줄이기 위해 고품질 경고를 받는 데 집중합니다. 경고는 로그 데이터, 에이전트 또는 기타 데이터에서 가져올 수 있습니다.", + "description": "Azure SQL의 모든 로그를 SIEM(보안 정보 및 이벤트 관리) 및 SOAR(보안 오케스트레이션 자동화 및 대응)로 전달하여 사용자 지정 위협 탐지를 설정하는 데 사용할 수 있습니다. 잠재적인 위협 및 변칙에 대해 다양한 유형의 Azure 자산을 모니터링하고 있는지 확인합니다. 분석가가 분류할 수 있는 오탐을 줄이기 위해 고품질 경고를 받는 데 집중합니다. 경고는 로그 데이터, 에이전트 또는 기타 데이터에서 제공될 수 있습니다.", "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "보통", - "subcategory": "SIEM/SOAR", - "text": "Azure SQL 데이터베이스 활동 로그 데이터가 SIEM/SOAR에 표시되는지 확인합니다." + "subcategory": "SIEM/소이어", + "text": "Azure SQL Database 활동 로그 데이터가 SIEM/SOAR에 표시되는지 확인합니다.", + "waf": "안전" }, { "category": "로깅", - "description": "SOC(보안 운영 센터) 팀은 인시던트 대응 계획(플레이북 또는 수동 응답)을 만들어 변조, 악의적인 활동 및 기타 비정상적인 동작을 조사하고 완화해야 합니다.", + "description": "SOC(보안 운영 센터) 팀은 변조, 악의적인 활동 및 기타 비정상적인 동작을 조사하고 완화하기 위해 인시던트 대응 계획(플레이북 또는 수동 응답)을 만들어야 합니다.", "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "보통", - "subcategory": "SIEM/SOAR", - "text": "악의적이거나 비정상적인 감사 로깅 이벤트에 대한 대응 계획이 있는지 확인" + "subcategory": "SIEM/소이어", + "text": "악의적이거나 비정상적인 감사 로깅 이벤트에 대한 대응 계획이 있는지 확인합니다.", + "waf": "안전" }, { "category": "네트워킹", - "description": "Azure SQL 데이터베이스용 Azure 포털에서 논리 서버를 만들면 공용 네트워크(공용 액세스)를 통해 표시되고 연결할 수 있는 공용 끝점이 생성됩니다. 그런 다음 방화벽 규칙 및 서비스 엔드포인트에 따라 연결을 제한할 수 있습니다. 프라이빗 엔드포인트(프라이빗 액세스)를 사용하여 내부 네트워크에 대한 연결만 제한하는 프라이빗 연결을 구성할 수도 있습니다. 프라이빗 엔드포인트를 사용하는 프라이빗 액세스는 지원할 수 없는 비즈니스 사례 또는 성능/기술적 이유가 적용되지 않는 한 기본값이어야 합니다. 프라이빗 엔드포인트의 사용에는 고려하고 평가해야 하는 성능 영향이 있습니다.", + "description": "Azure Portal에서 Azure SQL Database에 대한 논리 서버를 만들면 공용 네트워크(공용 액세스)를 통해 볼 수 있고 연결할 수 있는 공용 엔드포인트가 생성됩니다. 그런 다음 방화벽 규칙 및 서비스 엔드포인트에 따라 연결을 제한할 수 있습니다. 개인 엔드포인트(개인 액세스)를 사용하여 내부 네트워크에 대한 연결만 제한하는 개인 연결을 구성할 수도 있습니다. Private Endpoint를 사용하는 프라이빗 액세스는 지원할 수 없는 비즈니스 사례 또는 성능/기술적 이유가 적용되지 않는 한 기본값이어야 합니다. 프라이빗 엔드포인트의 사용에는 고려하고 평가해야 하는 성능 영향이 있습니다.", "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "높다", "subcategory": "인터넷", - "text": "공용 및 개인 액세스 연결 방법을 검토하고 워크로드에 적합한 방법을 선택합니다." + "text": "Public 및 Private Access 연결 방법을 검토하고 워크로드에 적합한 방법을 선택합니다.", + "waf": "안전" }, { "category": "네트워킹", - "description": "중요: 프라이빗 엔드포인트에 대한 연결은 프록시만 연결 정책으로 지원합니다. 프라이빗 엔드포인트를 사용하는 경우 연결은 Azure SQL 데이터베이스 게이트웨이를 통해 데이터베이스 노드로 프록시됩니다. 클라이언트는 직접 연결되지 않습니다.", + "description": "중요: 프라이빗 엔드포인트에 대한 연결은 연결 정책으로 프록시만 지원합니다. 프라이빗 엔드포인트를 사용하는 경우 연결은 Azure SQL Database 게이트웨이를 통해 데이터베이스 노드로 프록시됩니다. 클라이언트는 직접 연결되지 않습니다.", "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", "severity": "낮다", "subcategory": "인터넷", - "text": "다르게 필요하고 정당화되지 않는 경우 기본 Azure SQL 데이터베이스 연결 정책을 유지합니다." + "text": "다르지 않고 필요하고 정당한 경우 기본 Azure SQL Database 연결 정책 유지", + "waf": "안전" }, { "category": "네트워킹", - "description": "이 옵션은 다른 고객의 구독에서 연결을 포함하여 Azure의 모든 연결을 허용하도록 방화벽을 구성합니다. 이 옵션을 선택하는 경우 로그인 및 사용자 권한이 권한이 있는 사용자로만 액세스를 제한하는지 확인합니다. 꼭 필요한 것이 아닌 경우 이 설정을 OFF로 유지합니다.", + "description": "이 옵션은 다른 고객의 구독에서 연결을 포함하여 Azure의 모든 연결을 허용하도록 방화벽을 구성합니다. 이 옵션을 선택하는 경우 로그인 및 사용자 권한이 권한이 있는 사용자만 액세스할 수 있도록 제한해야 합니다. 반드시 필요한 경우가 아닌 경우 이 설정을 OFF로 유지합니다.", "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "높다", "subcategory": "인터넷", - "text": "Azure SQL 데이터베이스 방화벽에서 Azure 서비스 및 리소스가 이 서버에 액세스하도록 허용 설정이 비활성화되어 있는지 확인합니다." + "text": "Azure SQL Database 방화벽에서 Azure 서비스 및 리소스가 이 서버에 액세스할 수 있도록 허용 설정이 비활성화되어 있는지 확인합니다.", + "waf": "안전" }, { "category": "네트워킹", - "description": "Azure SQL 데이터베이스에는 외부 REST 엔드포인트와의 기본 통합을 허용하는 새로운 기본 제공 기능이 있습니다. 즉, Azure SQL 데이터베이스를 Azure 함수, Azure 논리 앱, 인지 서비스, 이벤트 허브, 이벤트 그리드, Azure 컨테이너, API 관리 및 일반적으로 모든 REST 또는 GraphQL 끝점과 통합합니다. 적절하게 제한되지 않으면 Azure SQL 데이터베이스 데이터베이스 내의 코드에서 이 메커니즘을 활용하여 데이터를 반출할 수 있습니다. 반드시 필요하지 않은 경우 아웃바운드 방화벽 규칙을 사용하여 이 기능을 차단하거나 제한하는 것이 좋습니다.", + "description": "Azure SQL Database에는 외부 REST 엔드포인트와 기본적으로 통합할 수 있는 새로운 기본 제공 기능이 있습니다. 즉, Azure SQL Database를 Azure Functions, Azure Logic Apps, Cognitive Services, Event Hubs, Event Grid, Azure Containers, API Management 및 일반적으로 모든 REST 또는 GraphQL 엔드포인트와 통합합니다. 적절하게 제한되지 않은 경우 Azure SQL Database 데이터베이스 내의 코드는 이 메커니즘을 활용하여 데이터를 반출할 수 있습니다. 반드시 필요한 경우가 아닌 경우 아웃바운드 방화벽 규칙을 사용하여 이 기능을 차단하거나 제한하는 것이 좋습니다.", "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", "severity": "보통", "subcategory": "아웃바운드 제어", - "text": "외부 엔드포인트에 대한 아웃바운드 REST API 호출 차단 또는 제한" + "text": "외부 엔드포인트에 대한 아웃바운드 REST API 호출 차단 또는 제한", + "waf": "안전" }, { "category": "네트워킹", - "description": "아웃바운드 방화벽 규칙은 Azure SQL 데이터베이스 논리 서버의 네트워크 트래픽을 Azure 저장소 계정 및 Azure SQL 데이터베이스 논리 서버의 고객 정의 목록으로 제한합니다. 이 목록에 없는 저장소 계정 또는 데이터베이스에 액세스하려는 모든 시도는 거부됩니다.", + "description": "아웃바운드 방화벽 규칙은 Azure SQL Database 논리 서버에서 Azure Storage 계정 및 Azure SQL Database 논리 서버의 고객 정의 목록으로 네트워크 트래픽을 제한합니다. 이 목록에 없는 스토리지 계정 또는 데이터베이스에 액세스하려는 모든 시도는 거부됩니다.", "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", "severity": "보통", "subcategory": "아웃바운드 제어", - "text": "아웃바운드 네트워크 액세스가 필요한 경우 기본 제공 Azure SQL Database 제어 기능을 사용하여 아웃바운드 네트워킹 제한을 구성하는 것이 좋습니다." + "text": "아웃바운드 네트워크 액세스가 필요한 경우 기본 제공 Azure SQL Database 제어 기능을 사용하여 아웃바운드 네트워킹 제한을 구성하는 것이 좋습니다", + "waf": "안전" }, { "category": "네트워킹", - "description": "프라이빗 엔드포인트는 Azure 가상 네트워크의 서브넷 내에 만들어집니다. NSG/ASG, UDR, 방화벽, 모니터링 및 감사를 포함하여 포함하는 네트워크 환경에도 적절한 보안 구성을 적용해야 합니다.", + "description": "프라이빗 엔드포인트는 Azure Virtual Network의 서브넷 내에 만들어집니다. NSG/ASG, UDR, 방화벽, 모니터링 및 감사를 포함한 포함하는 네트워크 환경에도 적절한 보안 구성을 적용해야 합니다.", "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "보통", - "subcategory": "비공개 액세스", - "text": "프라이빗 액세스 연결을 사용하는 경우 프라이빗 엔드포인트, Azure 가상 네트워크, Azure 방화벽 및 Azure 네트워크 보안 그룹 검사 목록을 사용하고 있는지 확인합니다." + "subcategory": "개인 액세스", + "text": "프라이빗 액세스 연결을 사용하는 경우 프라이빗 엔드포인트, Azure Virtual Network, Azure Firewall 및 Azure 네트워크 보안 그룹 검사 목록을 사용하고 있는지 확인합니다", + "waf": "안전" }, { "category": "네트워킹", - "description": "프라이빗 엔드포인트 연결을 추가할 때 논리 서버에 대한 퍼블릭 라우팅은 기본적으로 차단되지 않습니다. --방화벽 및 가상 네트워크-- 창에서 --공용 네트워크 액세스 거부-- 설정은 기본적으로 선택되어 있지 않습니다. 공용 네트워크 액세스를 사용하지 않도록 설정하려면 --공용 네트워크 액세스 거부를 선택해야 합니다--.", + "description": "프라이빗 엔드포인트 연결을 추가할 때 논리 서버에 대한 공용 라우팅은 기본적으로 차단되지 않습니다. --Firewall and virtual networks-- 창에서 --Deny public network access--- 설정은 기본적으로 선택되지 않습니다. 공용 네트워크 액세스를 사용하지 않도록 설정하려면 --Deny public network access를 선택해야 합니다--.", "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "높다", - "subcategory": "비공개 액세스", - "text": "프라이빗 엔드포인트(프라이빗 액세스)를 사용하는 경우 퍼블릭 액세스 연결을 사용하지 않도록 설정하는 것이 좋습니다." + "subcategory": "개인 액세스", + "text": "프라이빗 엔드포인트(프라이빗 액세스)를 사용하는 경우 공용 액세스 연결을 사용하지 않도록 설정하는 것이 좋습니다", + "waf": "안전" }, { "category": "네트워킹", "description": "이제 NSG(네트워크 보안 그룹) 및 ASG(애플리케이션 보안 그룹)를 프라이빗 엔드포인트가 포함된 서브넷에 적용하여 내부 원본 IP 범위에 따라 Azure SQLDB에 대한 연결을 제한할 수 있습니다.", "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", "severity": "보통", - "subcategory": "비공개 액세스", - "text": "프라이빗 엔드포인트(프라이빗 액세스)를 사용하는 경우 NSG 및 최종적으로 ASG를 적용하여 들어오는 원본 IP 주소 범위를 제한합니다." + "subcategory": "개인 액세스", + "text": "프라이빗 엔드포인트(프라이빗 액세스)를 사용하는 경우 NSG 및 ASG를 적용하여 들어오는 원본 IP 주소 범위를 제한합니다", + "waf": "안전" }, { "category": "네트워킹", - "description": "관리되는 인스턴스(SQL MI)는 외부 액세스를 방지하기 위해 가상 네트워크 내에서 격리될 수 있습니다. 동일한 지역의 동일하거나 피어링된 가상 네트워크에 있는 애플리케이션 및 도구는 직접 액세스할 수 있습니다. 다른 지역에 있는 응용 프로그램 및 도구는 가상 네트워크 간 연결 또는 ExpressRoute 회로 피어링을 사용하여 연결을 설정할 수 있습니다. 고객은 NSG(네트워크 보안 그룹)와 결국 내부 방화벽을 사용하여 포트 1433을 통한 액세스를 관리되는 인스턴스에 액세스해야 하는 리소스로만 제한해야 합니다.", + "description": "SQL MI(Managed Instance)는 외부 액세스를 방지하기 위해 가상 네트워크 내에서 격리될 수 있습니다. 동일한 지역의 동일하거나 피어링된 가상 네트워크에 있는 애플리케이션 및 도구는 직접 액세스할 수 있습니다. 다른 지역에 있는 애플리케이션 및 도구는 가상 네트워크-가상 네트워크 연결 또는 ExpressRoute 회로 피어링을 사용하여 연결을 설정할 수 있습니다. 고객은 NSG(네트워크 보안 그룹) 및 내부 방화벽을 사용하여 포트 1433을 통한 액세스를 관리되는 인스턴스에 대한 액세스가 필요한 리소스로만 제한해야 합니다.", "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", "severity": "보통", - "subcategory": "비공개 액세스", - "text": "NSG(네트워크 보안 그룹) 및 방화벽 규칙을 적용하여 Azure SQL 관리되는 인스턴스 내부 서브넷에 대한 액세스를 제한합니다." + "subcategory": "개인 액세스", + "text": "NSG(네트워크 보안 그룹) 및 방화벽 규칙을 적용하여 Azure SQL Managed Instance 내부 서브넷에 대한 액세스를 제한합니다.", + "waf": "안전" }, { "category": "네트워킹", - "description": "Azure 가상 네트워크 서비스 엔드포인트는 리디렉션 정책을 사용하여 Azure SQL 데이터베이스 백 엔드 노드에 직접 연결하려는 경우 기본 솔루션입니다. 이렇게 하면 고성능 모드에서 액세스할 수 있으며 성능 관점에서 권장되는 접근 방식입니다.", + "description": "Azure Virtual Network 서비스 엔드포인트는 리디렉션 정책을 사용하여 Azure SQL Database 백 엔드 노드에 대한 직접 연결을 설정하려는 경우 선호되는 솔루션입니다. 이렇게 하면 고성능 모드에서 액세스할 수 있으며 성능 관점에서 권장되는 접근 방식입니다.", "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", "severity": "높다", "subcategory": "공개 액세스", - "text": "공용 액세스 연결을 사용하는 경우 서비스 엔드포인트를 활용하여 선택한 Azure 가상 네트워크의 액세스를 제한합니다." + "text": "공용 액세스 연결을 사용하는 경우 서비스 엔드포인트를 활용하여 선택한 Azure Virtual Network의 액세스를 제한합니다.", + "waf": "안전" }, { "category": "네트워킹", - "description": "Azure SQL 데이터베이스 방화벽을 사용하면 통신이 허용되는 IP 주소 범위를 지정할 수 있습니다. 이 방법은 Azure 개인 네트워크 외부에 있는 안정적인 IP 주소에 적합합니다.", + "description": "Azure SQL Database 방화벽을 사용하면 통신이 허용되는 IP 주소 범위를 지정할 수 있습니다. 이 방법은 Azure 개인 네트워크 외부에 있는 안정적인 IP 주소에 적합합니다.", "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "보통", "subcategory": "공개 액세스", - "text": "공용 액세스 연결을 사용하는 경우 알려진 특정 IP만 방화벽에 추가되었는지 확인합니다." + "text": "공용 액세스 연결을 사용하는 경우 알려진 특정 IP만 방화벽에 추가되어야 합니다", + "waf": "안전" }, { "category": "네트워킹", - "description": "가능하면 데이터베이스 수준 IP 방화벽 규칙을 사용하는 것이 좋습니다. 이렇게 하면 보안이 강화되고 데이터베이스의 이식성이 향상됩니다. 관리자에 대해 서버 수준 IP 방화벽 규칙을 사용합니다. 또한 액세스 요구 사항이 동일한 데이터베이스가 많고 각 데이터베이스를 개별적으로 구성하지 않으려는 경우에도 사용합니다.", + "description": "가능하면 데이터베이스 수준 IP 방화벽 규칙을 사용하는 것이 좋습니다. 이렇게 하면 보안이 강화되고 데이터베이스의 이식성이 향상됩니다. 관리자를 위해 서버 수준 IP 방화벽 규칙을 사용합니다. 또한 동일한 액세스 요구 사항을 가진 데이터베이스가 많고 각 데이터베이스를 개별적으로 구성하지 않으려는 경우에도 사용합니다.", "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", "severity": "낮다", "subcategory": "공개 액세스", - "text": "공용 액세스 연결이 Azure SQL 데이터베이스 방화벽 규칙에 의해 사용되고 제어되는 경우 서버 수준 IP 규칙보다 데이터베이스 수준 사용" + "text": "공용 액세스 연결을 사용하고 Azure SQL Database 방화벽 규칙에 의해 제어되는 경우 서버 수준 IP 규칙을 통해 데이터베이스 수준을 사용합니다", + "waf": "안전" }, { "category": "네트워킹", - "description": "관리되는 인스턴스(SQL MI)는 외부 액세스를 방지하기 위해 가상 네트워크 내에서 격리될 수 있습니다. 관리되는 인스턴스 퍼블릭 엔드포인트는 기본적으로 사용하도록 설정되지 않으며, 엄격하게 필요한 경우에만 명시적으로 사용하도록 설정해야 합니다. 회사 정책에서 퍼블릭 엔드포인트 사용을 허용하지 않는 경우 Azure Policy를 사용하여 퍼블릭 엔드포인트를 처음부터 사용하도록 설정하지 않도록 합니다.", + "description": "SQL MI(Managed Instance)는 외부 액세스를 방지하기 위해 가상 네트워크 내에서 격리될 수 있습니다. Managed Instance 공용 엔드포인트는 기본적으로 사용하도록 설정되지 않으며, 반드시 필요한 경우에만 명시적으로 사용하도록 설정해야 합니다. 회사 정책에서 퍼블릭 엔드포인트의 사용을 허용하지 않는 경우 Azure Policy를 사용하여 처음부터 퍼블릭 엔드포인트를 사용하도록 설정하지 않도록 합니다.", "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "높다", "subcategory": "공개 액세스", - "text": "Azure SQL 관리 되는 인스턴스 공용 끝점을 사용 하도록 설정 하지 마십시오." + "text": "Azure SQL Managed Instance 퍼블릭 엔드포인트를 사용하도록 설정하지 마세요.", + "waf": "안전" }, { "category": "네트워킹", - "description": "관리되는 인스턴스(SQL MI) 퍼블릭 엔드포인트는 기본적으로 사용하도록 설정되지 않으며, 엄격하게 필요한 경우에만 명시적으로 사용하도록 설정해야 합니다. 이 경우 NSG(네트워크 보안 그룹)를 적용하여 포트 3342에 대한 액세스를 신뢰할 수 있는 원본 IP 주소로만 제한하는 것이 좋습니다.", + "description": "SQL MI(Managed Instance) 퍼블릭 엔드포인트는 기본적으로 사용하도록 설정되지 않으며, 반드시 필요한 경우에만 명시적으로 사용하도록 설정해야 합니다. 이 경우 NSG(네트워크 보안 그룹)를 적용하여 포트 3342에 대한 액세스를 신뢰할 수 있는 원본 IP 주소로만 제한하는 것이 좋습니다.", "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "높다", "subcategory": "공개 액세스", - "text": "Azure SQL 관리되는 인스턴스 퍼블릭 엔드포인트가 필요한 경우 액세스 제한" + "text": "Azure SQL Managed Instance 퍼블릭 엔드포인트가 필요한 경우 액세스 제한", + "waf": "안전" }, { "category": "권한 있는 액세스", - "description": "Microsoft 직원 및 하위 프로세서가 수행하는 대부분의 작업, 지원 및 문제 해결에는 고객 데이터에 액세스할 필요가 없습니다. 이러한 액세스가 필요한 드문 상황에서 Microsoft Azure용 고객 Lockbox는 고객이 고객 데이터 액세스 요청을 검토하고 승인하거나 거부할 수 있는 인터페이스를 제공합니다. Microsoft가 고객 데이터에 액세스해야 하는 지원 시나리오에서 Azure SQL 데이터베이스는 고객 데이터 액세스 요청을 검토하고 승인하거나 거부할 수 있는 인터페이스를 제공하기 위해 고객 Lockbox를 지원합니다.", + "description": "Microsoft 직원 및 하위 프로세서가 수행하는 대부분의 작업, 지원 및 문제 해결에는 고객 데이터에 대한 액세스가 필요하지 않습니다. 이러한 액세스가 필요한 드문 상황에서 Microsoft Azure용 고객 Lockbox는 고객이 고객 데이터 액세스 요청을 검토하고 승인하거나 거부할 수 있는 인터페이스를 제공합니다. Microsoft가 고객 데이터에 액세스해야 하는 지원 시나리오에서 Azure SQL Database는 고객 Lockbox를 지원하여 고객 데이터 액세스 요청을 검토하고 승인하거나 거부할 수 있는 인터페이스를 제공합니다.", "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", "severity": "낮다", - "subcategory": "사물함", - "text": "Microsoft 직원의 Azure SQL 데이터베이스 액세스에 대한 고객 Lockbox를 검토하고 사용하도록 설정" + "subcategory": "자물쇠 상자", + "text": "Microsoft 직원이 Azure SQL Database 액세스를 위한 고객 Lockbox 검토 및 사용", + "waf": "안전" }, { "category": "권한 있는 액세스", - "description": "최소 권한의 원칙에 따르면 사용자는 작업을 완료하는 데 필요한 것보다 더 많은 권한을 가질 수 없습니다. 권한이 높은 데이터베이스 및 서버 사용자는 데이터베이스에서 많은 구성 및 유지 관리 작업을 수행할 수 있으며 Azure SQL 인스턴스에서 데이터베이스를 삭제할 수도 있습니다. 데이터베이스 소유자 및 권한 있는 계정을 추적하는 것은 과도한 권한을 갖지 않도록 하는 데 중요합니다.", + "description": "최소 권한의 원칙은 사용자가 작업을 완료하는 데 필요한 것보다 더 많은 권한을 가져서는 안 된다는 것입니다. 권한이 높은 데이터베이스 및 서버 사용자는 데이터베이스에서 많은 구성 및 유지 관리 작업을 수행할 수 있으며 Azure SQL 인스턴스에서 데이터베이스를 삭제할 수도 있습니다. 데이터베이스 소유자 및 권한 있는 계정을 추적하는 것은 과도한 권한을 갖지 않도록 하는 데 중요합니다.", "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", "severity": "보통", "subcategory": "권한을", - "text": "사용자에게 작업 기능을 완료하기 위해 필요한 최소 수준의 액세스 권한이 할당되었는지 확인" + "text": "사용자에게 직무를 완료하는 데 필요한 최소 수준의 액세스 권한이 할당되었는지 확인합니다.", + "waf": "안전" }, { "category": "권한 있는 액세스", - "description": "ID(사용자 및 SPN 모두)는 기능을 수행하는 데 필요한 최소 액세스 권한으로 범위를 지정해야 합니다. 관련이 없는 여러 사용 권한 집합이 있는 하나의 SPN을 사용하는 대신 더 많은 수의 엄격한 범위의 SPN을 사용해야 합니다. 예를 들어 온-프레미스에서 Azure SQL 데이터베이스에 대한 쿼리를 수행하는 세 개의 외부 웹 응용 프로그램이 있는 경우 이러한 작업에 모두 동일한 SPN을 사용해서는 안 됩니다. 대신 각각 범위가 엄격하게 지정된 SPN이 있어야 합니다.", + "description": "ID(사용자 및 SPN 모두)는 기능을 수행하는 데 필요한 최소한의 액세스 범위로 범위를 지정해야 합니다. 여러 관련 없는 권한 집합이 있는 하나의 SPN 대신 더 많은 수의 엄격한 범위의 SPN을 사용해야 합니다. 예를 들어 Azure SQL Database에 쿼리를 수행하는 온-프레미스에서 호스팅되는 세 개의 외부 웹 응용 프로그램이 있는 경우 모두 이러한 작업에 동일한 SPN을 사용해서는 안 됩니다. 대신 각각 범위가 좁은 SPN이 있어야 합니다.", "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", "severity": "낮다", "subcategory": "권한을", - "text": "고유한 응용 프로그램에 Azure SQL 데이터베이스에 액세스할 수 있는 최소 권한으로 다른 자격 증명이 할당되는지 확인" + "text": "개별 응용 프로그램에 Azure SQL Database에 액세스할 수 있는 최소한의 권한이 있는 다른 자격 증명이 할당되도록 합니다.", + "waf": "안전" } ], "metadata": { - "name": "Azure SQLDB Security Checklist (Preview)" + "name": "Azure SQLDB Security Checklist (Preview)", + "state": "Preview", + "timestamp": "October 23, 2024" }, "severities": [ { @@ -494,24 +593,49 @@ ], "status": [ { - "description": "이 검사는 아직 검토되지 않았습니다.", + "description": "이 검사는 아직 검토되지 않았습니다", "name": "확인되지 않음" }, { - "description": "이 검사와 연결된 작업 항목이 있습니다.", + "description": "이 검사와 연관된 작업 항목이 있습니다", "name": "열다" }, { - "description": "이 검사가 확인되었으며 연결된 추가 작업 항목이 없습니다.", + "description": "이 검사는 확인되었으며 이와 관련된 추가 작업 항목이 없습니다", "name": "성취" }, { - "description": "권장 사항을 이해했지만 현재 요구 사항에서 필요하지 않음", - "name": "필요하지 않음" + "description": "권장 사항을 이해했지만 현재 요구 사항에 필요하지 않음", + "name": "필요 없음" }, { - "description": "현재 디자인에는 적용되지 않음", + "description": "현재 설계에는 적용되지 않습니다.", "name": "해당 없음" } + ], + "waf": [ + { + "name": "신뢰도" + }, + { + "name": "안전" + }, + { + "name": "비용" + }, + { + "name": "작업" + }, + { + "name": "공연" + } + ], + "yesno": [ + { + "name": "예" + }, + { + "name": "아니요" + } ] } \ No newline at end of file diff --git a/checklists/sqldb_checklist.pt.json b/checklists/sqldb_checklist.pt.json index 62c70f2d..9ed22c8b 100644 --- a/checklists/sqldb_checklist.pt.json +++ b/checklists/sqldb_checklist.pt.json @@ -1,5 +1,4 @@ { - "$schema": "checklist.schema.json", "categories": [ { "name": "BCDR" @@ -40,446 +39,546 @@ "category": "BCDR", "description": "Certifique-se de que seus backups estejam protegidos contra ataques. Isso deve incluir a criptografia dos backups para proteger contra a perda de confidencialidade. Para backup de serviço regular do Azure, os dados de backup são criptografados automaticamente usando chaves gerenciadas pela plataforma do Azure. Você também pode optar por criptografar o backup usando uma chave gerenciada pelo cliente. Nesse caso, verifique se essa chave gerenciada pelo cliente no cofre de chaves também está no escopo de backup.", "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", "severity": "Média", - "subcategory": "Cofre da Chave do Azure", - "text": "Proteja seus dados de backup com criptografia e armazene chaves com segurança no Cofre de Chaves do Azure" + "subcategory": "Azure Key Vault", + "text": "Proteja seus dados de backup com criptografia e armazene chaves com segurança no Azure Key Vault", + "waf": "Segurança" }, { "category": "BCDR", - "description": "O Banco de Dados SQL do Azure usa a tecnologia do SQL Server para criar backups completos a cada semana, backup diferencial a cada 12 a 24 horas e backup de log de transações a cada 5 a 10 minutos. Por padrão, o Banco de dados SQL armazena dados em blobs de armazenamento com redundância geográfica que são replicados para uma região emparelhada.", + "description": "O Banco de Dados SQL do Azure usa a tecnologia SQL Server para criar backups completos todas as semanas, backup diferencial a cada 12 a 24 horas e backup de log de transações a cada 5 a 10 minutos. Por padrão, o Banco de Dados SQL armazena dados em blobs de armazenamento com redundância geográfica que são replicados para uma região emparelhada.", "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", "severity": "Média", "subcategory": "Backup", - "text": "Configurar backups automatizados do Banco de Dados SQL do Azure" + "text": "Configurar backups automatizados do Banco de Dados SQL do Azure", + "waf": "Segurança" }, { "category": "BCDR", - "description": "Por padrão, o Banco de dados SQL armazena dados em blobs de armazenamento com redundância geográfica que são replicados para uma região emparelhada. Para o Banco de dados SQL, a redundância de armazenamento de backup pode ser configurada no momento da criação do banco de dados ou pode ser atualizada para um banco de dados existente; as alterações feitas em um banco de dados existente se aplicam somente a backups futuros.", + "description": "Por padrão, o Banco de Dados SQL armazena dados em blobs de armazenamento com redundância geográfica que são replicados para uma região emparelhada. Para o Banco de Dados SQL, a redundância de armazenamento de backup pode ser configurada no momento da criação do banco de dados ou pode ser atualizada para um banco de dados existente; As alterações feitas em um banco de dados existente se aplicam apenas a backups futuros.", "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", "severity": "Baixo", "subcategory": "Backup", - "text": "Habilite o armazenamento de backup com redundância geográfica para proteger contra falhas em uma única região e perda de dados" + "text": "Habilite o armazenamento de backup com redundância geográfica para proteger contra falhas de região única e perda de dados", + "waf": "Segurança" }, { "category": "Código", - "description": "O código mal-intencionado pode potencialmente contornar os controles de segurança. Antes de implantar o código personalizado na produção, é essencial revisar o que está sendo implantado. Use uma ferramenta de banco de dados como o Azure Data Studio que dá suporte ao controle do código-fonte. Implementar ferramentas e lógica para análise de código, vulnerabilidade e verificação de credenciais.", + "description": "O código mal-intencionado pode contornar os controles de segurança. Antes de implantar o código personalizado na produção, é essencial examinar o que está sendo implantado. Use uma ferramenta de banco de dados como o Azure Data Studio que dá suporte ao controle do código-fonte. Implemente ferramentas e lógica para análise de código, vulnerabilidade e verificação de credenciais.", "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "Média", - "subcategory": "Controle do código-fonte e revisão de código", - "text": "Usar sistemas de Controle do Código-Fonte para armazenar, manter e revisar o código do aplicativo implantado no Banco de Dados SQLDB do Azure" + "subcategory": "Controle de código-fonte e revisão de código", + "text": "Usar sistemas de controle do código-fonte para armazenar, manter e examinar o código do aplicativo implantado no banco de dados SQL do Azure", + "waf": "Segurança" }, { "category": "Descoberta e classificação de dados", - "description": "Em caso de requisitos de classificação, a Purview é a opção preferida. Use apenas a Descoberta e Classificação de Dados SQL caso o Purview não seja uma opção. Descubra colunas que potencialmente contêm dados confidenciais. O que é considerado dados confidenciais depende muito do cliente, da regulamentação de conformidade, etc., e precisa ser avaliado pelos usuários responsáveis por esses dados. Classifique as colunas para usar cenários avançados de auditoria e proteção baseados em sensibilidade. Revise os resultados da descoberta automatizada e finalize a classificação, se necessário.", + "description": "No caso de requisitos de classificação, o Purview é a opção preferencial. Use a Descoberta e Classificação de Dados SQL somente caso o Purview não seja uma opção. Descubra colunas que potencialmente contêm dados confidenciais. O que é considerado dado sensível depende muito do cliente, da regulamentação de conformidade, etc., e precisa ser avaliado pelos usuários responsáveis por esses dados. Classifique as colunas para usar cenários avançados de auditoria e proteção baseados em confidencialidade. Revise os resultados da descoberta automatizada e finalize a classificação, se necessário.", "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", "severity": "Baixo", "subcategory": "Descoberta e classificação de dados", - "text": "Planejar e configurar a Descoberta e Classificação de Dados para proteger os dados confidenciais" + "text": "Planejar e configurar a descoberta e classificação de dados para proteger os dados confidenciais", + "waf": "Segurança" }, { "category": "Mascaramento de dados", - "description": "O uso desse recurso é recomendado somente se a criptografia de coluna não for uma opção e houver um requisito específico para preservar tipos e formatos de dados. O mascaramento dinâmico de dados limita a exposição de dados confidenciais, mascarando-os para usuários não privilegiados. O mascaramento dinâmico de dados ajuda a impedir o acesso não autorizado a dados confidenciais, permitindo que os clientes designem a quantidade de dados confidenciais a serem revelados com impacto mínimo na camada de aplicativo.", + "description": "O uso desse recurso é recomendado somente se a criptografia de coluna não for uma opção e houver um requisito específico para preservar tipos e formatos de dados. O mascaramento de dados dinâmicos limita a exposição de dados confidenciais, mascarando-os para usuários sem privilégios. O mascaramento dinâmico de dados ajuda a impedir o acesso não autorizado a dados confidenciais, permitindo que os clientes designem a quantidade de dados confidenciais a serem revelados com impacto mínimo na camada de aplicativo.", "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", "severity": "Baixo", "subcategory": "Mascaramento de dados", - "text": "Use o mascaramento de dados para impedir o acesso não autorizado a dados de usuários não administradores se nenhuma criptografia for possível" + "text": "Use o Mascaramento de Dados para impedir o acesso a dados de usuários não administradores não autorizados se nenhuma criptografia for possível", + "waf": "Segurança" }, { "category": "Defensor", - "description": "O SQL Advanced Threat Detection (ATP) fornece uma camada de segurança que detecta possíveis vulnerabilidades e atividades anômalas em bancos de dados, como ataques de injeção de SQL e padrões de comportamento incomuns. Quando uma ameaça potencial é detectada, a Detecção de Ameaças envia um alerta acionável em tempo real por email e no Microsoft Defender para Nuvem, que inclui etapas claras de investigação e correção para a ameaça específica.", + "description": "A ATP (Detecção Avançada de Ameaças) do SQL fornece uma camada de segurança que detecta possíveis vulnerabilidades e atividades anômalas em bancos de dados, como ataques de injeção de SQL e padrões de comportamento incomuns. Quando uma ameaça potencial é detectada, a Detecção de Ameaças envia um alerta acionável em tempo real por email e no Microsoft Defender para Nuvem, que inclui etapas claras de investigação e correção para a ameaça específica.", "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "Alto", - "subcategory": "Proteção Avançada contra Ameaças", - "text": "Revise e conclua a configuração da Proteção Avançada contra Ameaças (ATP)" + "subcategory": "Proteção avançada contra ameaças", + "text": "Revise e conclua a configuração da Proteção Avançada contra Ameaças (ATP)", + "waf": "Segurança" }, { "category": "Defensor", - "description": "Habilite o Microsoft Defender para SQL do Azure no nível de assinatura para integrar e proteger automaticamente todos os servidores e bancos de dados existentes e futuros. Quando você habilita no nível de assinatura, todos os bancos de dados no Banco de Dados SQL do Azure e na Instância Gerenciada SQL do Azure são protegidos. Você pode desativá-los individualmente, se desejar. Se você quiser gerenciar manualmente quais bancos de dados estão protegidos, desabilite no nível de assinatura e habilite cada banco de dados que deseja proteger.", + "description": "Habilite o Microsoft Defender para SQL do Azure no nível da assinatura para integrar e proteger automaticamente todos os servidores e bancos de dados existentes e futuros. Quando você habilita no nível da assinatura, todos os bancos de dados no Banco de Dados SQL do Azure e na Instância Gerenciada de SQL do Azure são protegidos. Você pode desativá-los individualmente, se desejar. Se você quiser gerenciar manualmente quais bancos de dados estão protegidos, desabilite no nível da assinatura e habilite cada banco de dados que você deseja proteger.", "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", "severity": "Alto", "subcategory": "Defender para SQL do Azure", - "text": "Habilitar o Microsoft Defender para SQL do Azure" + "text": "Habilitar o Microsoft Defender para SQL do Azure", + "waf": "Segurança" }, { "category": "Defensor", - "description": "O Microsoft Defender para Azure SQL ATP detecta atividades anômalas que indicam tentativas incomuns e potencialmente prejudiciais de acessar ou explorar bancos de dados. Os alertas podem ser configurados e gerados e serão relatados no console do Defender for.", + "description": "O Microsoft Defender para Azure SQL ATP detecta atividades anômalas que indicam tentativas incomuns e potencialmente prejudiciais de acessar ou explorar bancos de dados. Os alertas podem ser configurados e gerados e serão relatados no Defender para console.", "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", "severity": "Alto", "subcategory": "Defender para SQL do Azure", - "text": "Preparar um plano de resposta de segurança para reagir prontamente aos alertas SQL do Microsoft Defender para Azure" + "text": "Preparar um plano de resposta de segurança para reagir prontamente aos alertas de SQL do Microsoft Defender para Azure", + "waf": "Segurança" }, { "category": "Defensor", - "description": "A avaliação de vulnerabilidade do SQLDB do Azure é um serviço que fornece visibilidade do seu estado de segurança. A avaliação de vulnerabilidades inclui etapas acionáveis para resolver problemas de segurança e aprimorar a segurança do banco de dados. Ele pode ajudá-lo a monitorar um ambiente de banco de dados dinâmico onde as alterações são difíceis de controlar e melhorar sua postura de segurança SQL.", + "description": "A avaliação de vulnerabilidade do SQL do Azure é um serviço que fornece visibilidade do seu estado de segurança. A avaliação de vulnerabilidades inclui etapas acionáveis para resolver problemas de segurança e aprimorar a segurança do banco de dados. Ele pode ajudá-lo a monitorar um ambiente de banco de dados dinâmico em que as alterações são difíceis de rastrear e melhorar sua postura de segurança SQL.", "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", "severity": "Alto", "subcategory": "Avaliação de vulnerabilidade", - "text": "Configurar descobertas de Avaliação de Vulnerabilidade (VA) e recomendações de revisão" + "text": "Configurar as descobertas da Avaliação de Vulnerabilidade (VA) e as recomendações de revisão", + "waf": "Segurança" }, { "category": "Defensor", - "description": "O Microsoft Defender para Nuvem fornece avaliação de vulnerabilidade para seus Bancos de Dados SQL do Azure. A avaliação de vulnerabilidades verifica seus bancos de dados em busca de vulnerabilidades de software e fornece uma lista de descobertas. Você pode usar as descobertas para corrigir vulnerabilidades de software e desabilitar as descobertas.", + "description": "O Microsoft Defender para Nuvem fornece avaliação de vulnerabilidade para seus Bancos de Dados SQL do Azure. A avaliação de vulnerabilidades verifica seus bancos de dados em busca de vulnerabilidades de software e fornece uma lista de descobertas. Você pode usar as descobertas para corrigir vulnerabilidades de software e desabilitar descobertas.", "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", "severity": "Alto", "subcategory": "Avaliação de vulnerabilidade", - "text": "Revisar regularmente as descobertas e recomendações da Avaliação de Vulnerabilidade (VA) e preparar um plano para corrigir" + "text": "Revisar regularmente as descobertas e recomendações da Avaliação de Vulnerabilidade (VA) e preparar um plano para corrigir", + "waf": "Segurança" }, { "category": "Encriptação", - "description": "O Always Encrypted with Secure Enclaves expande os recursos de computação confidencial do Always Encrypted, permitindo criptografia in-loco e consultas confidenciais mais ricas. O Always Encrypted with Secure Enclaves aborda essas limitações, permitindo alguns cálculos em dados de texto sem formatação dentro de um enclave seguro no lado do servidor. O uso desse recurso é recomendado para os casos em que você precisa limitar o acesso de administrador e precisa que suas consultas ofereçam suporte a mais do que a correspondência de igualdade de colunas criptografadas.", + "description": "O Always Encrypted com Secure Enclaves expande os recursos de computação confidencial do Always Encrypted, permitindo a criptografia in-loco e consultas confidenciais mais avançadas. O Always Encrypted with Secure Enclaves aborda essas limitações, permitindo alguns cálculos em dados de texto não criptografado dentro de um enclave seguro no lado do servidor. O uso desse recurso é recomendado para os casos em que você precisa limitar o acesso do administrador e precisa que suas consultas ofereçam suporte a mais do que a correspondência de igualdade de colunas criptografadas.", "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", "severity": "Média", "subcategory": "Sempre criptografado", - "text": "Se a proteção de dados PII confidenciais de usuários administradores for um requisito fundamental, mas as limitações da Criptografia de Coluna não puderem ser toleradas, considere a adoção do Always Encrypted with Secure Enclaves" + "text": "Se a proteção de dados confidenciais de PII de usuários administradores for um requisito importante, mas as limitações de criptografia de coluna não puderem ser toleradas, considere a adoção do Always Encrypted com Secure Enclaves", + "waf": "Segurança" }, { "category": "Encriptação", - "description": "Com o Banco de Dados SQL do Azure, você pode aplicar criptografia simétrica a uma coluna de dados usando Transact-SQL. Essa abordagem é chamada de criptografia de coluna, porque você pode usá-la para criptografar colunas específicas com chaves de criptografia diferentes. Isso oferece uma capacidade de criptografia mais granular do que o TDE, que criptografa dados em páginas. Usando Sempre Criptografado para garantir que dados confidenciais não sejam expostos em texto sem formatação no Banco de Dados SQL do Azure ou na Instância Gerenciada SQL, mesmo na memória/em uso. O Always Encrypted protege os dados de administradores de banco de dados (DBAs) e administradores de nuvem (ou agentes mal-intencionados que podem se passar por usuários com privilégios altos, mas não autorizados) e oferece mais controle sobre quem pode acessar seus dados.", + "description": "Com o Banco de Dados SQL do Azure, você pode aplicar criptografia simétrica a uma coluna de dados usando o Transact-SQL. Essa abordagem é chamada de criptografia de coluna, porque você pode usá-la para criptografar colunas específicas com chaves de criptografia diferentes. Isso oferece uma capacidade de criptografia mais granular do que a TDE, que criptografa dados em páginas. Usando o Always Encrypted para garantir que dados confidenciais não sejam expostos em texto não criptografado no Banco de Dados SQL do Azure ou na Instância Gerenciada de SQL, mesmo na memória/em uso. O Always Encrypted protege os dados de administradores de banco de dados (DBAs) e administradores de nuvem (ou agentes mal-intencionados que podem representar usuários altamente privilegiados, mas não autorizados) e oferece mais controle sobre quem pode acessar seus dados.", "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", "severity": "Baixo", "subcategory": "Criptografia de coluna", - "text": "Para proteger dados confidenciais de PII de usuários não administradores em colunas de tabela específicas, considere o uso de Criptografia de Coluna" + "text": "Para proteger dados confidenciais de PII de usuários não administradores em colunas de tabela específicas, considere usar a criptografia de coluna", + "waf": "Segurança" }, { "category": "Encriptação", - "description": "Habilitada por padrão, a TDE (Transparent Data Encryption, criptografia transparente de dados) ajuda a proteger os arquivos de banco de dados contra a divulgação de informações, executando criptografia e descriptografia em tempo real do banco de dados, backups associados e arquivos de log de transações 'em repouso', sem exigir alterações no aplicativo.", + "description": "Habilitada por padrão, a TDE (Transparent Data Encryption) ajuda a proteger os arquivos de banco de dados contra a divulgação de informações, executando criptografia e descriptografia em tempo real do banco de dados, backups associados e arquivos de log de transações 'em repouso', sem exigir alterações no aplicativo.", "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", "severity": "Alto", "subcategory": "Criptografia de dados transparente", - "text": "Garantir que a Criptografia de Dados Transparente (TDE) seja mantida habilitada" + "text": "Certifique-se de que a TDE (Transparent Data Encryption) seja mantida ativada", + "waf": "Segurança" }, { "category": "Encriptação", - "description": "Se for necessária a separação de funções no gerenciamento de chaves e dados dentro da organização, aproveite a CMK (Customer Managed Keys) para TDE (Transparent Data Encryption) para seu SQLDB do Azure e use o Cofre de Chaves do Azure para armazenar (consulte sua lista de verificação). Aproveite esse recurso quando você tiver requisitos de segurança rigorosos que não podem ser atendidos pelas chaves de serviço gerenciadas.", + "description": "Se a separação de tarefas no gerenciamento de chaves e dados dentro da organização for necessária, aproveite as CMKs (Chaves Gerenciadas pelo Cliente) para TDE (Transparent Data Encryption) para seu SQL do Azure Aproveite esse recurso quando você tiver requisitos de segurança rígidos que não podem ser atendidos pelas chaves de serviço gerenciadas.", "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", "severity": "Média", "subcategory": "Criptografia de dados transparente", - "text": "Use chaves gerenciadas pelo cliente (CMK) no Cofre de Chaves do Azure (AKV) se precisar de maior transparência e controle granular sobre a proteção TDE" + "text": "Use CMK (chaves gerenciadas pelo cliente) no AKV (Azure Key Vault) se precisar de maior transparência e controle granular sobre a proteção de TDE", + "waf": "Segurança" }, { "category": "Encriptação", - "description": "A configuração de versão mínima de TLS (Transport Layer Security) permite que os clientes escolham qual versão do TLS seu banco de dados SQL usa. É possível alterar a versão mínima do TLS usando o portal do Azure, o Azure PowerShell e a CLI do Azure.", + "description": "A configuração mínima de versão do TLS (Transport Layer Security) permite que os clientes escolham qual versão do TLS seu banco de dados SQL usa. É possível alterar a versão mínima do TLS usando o portal do Azure, o Azure PowerShell e a CLI do Azure.", "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", "severity": "Alto", "subcategory": "Segurança da camada de transporte", - "text": "Impor a versão mínima do TLS à versão mais recente disponível" + "text": "Impor a versão mínima do TLS para a mais recente disponível", + "waf": "Segurança" }, { "category": "Identidade", - "description": "Use a autenticação do Azure Active Directory (Azure AD) para gerenciamento centralizado de identidades. Use a Autenticação SQL somente se realmente necessário e documente como exceções.", + "description": "Use a autenticação do Azure Active Directory (Azure AD) para gerenciamento centralizado de identidades. Use a autenticação SQL somente se realmente necessário e documente como exceções.", "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", "severity": "Média", "subcategory": "Azure Active Directory", - "text": "Aproveitar a autenticação do Azure AD para conexões com os Bancos de Dados SQL do Azure" + "text": "Aproveite a autenticação do Azure AD para conexões com bancos de dados SQL do Azure", + "waf": "Segurança" }, { "category": "Identidade", - "description": "O uso de grupos do Azure AD simplifica o gerenciamento de permissões e tanto o proprietário do grupo quanto o proprietário do recurso podem adicionar/remover membros de/para o grupo. Crie um grupo separado para administradores do Azure AD para cada servidor lógico. Monitore as alterações de associação de grupo do Azure AD usando os relatórios de atividade de auditoria do Azure AD.", + "description": "O uso de grupos do Azure AD simplifica o gerenciamento de permissões e o proprietário do grupo e o proprietário do recurso podem adicionar/remover membros de/para o grupo. Crie um grupo separado para administradores do Azure AD para cada servidor lógico. Monitore as alterações de associação de grupo do Azure AD usando relatórios de atividades de auditoria do Azure AD.", "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", "severity": "Média", "subcategory": "Azure Active Directory", - "text": "Criar um grupo separado do Azure AD com duas contas de administrador para cada servidor lógico do Banco de Dados SQL do Azure" + "text": "Criar um grupo separado do Azure AD com duas contas de administrador para cada servidor lógico do Banco de Dados SQL do Azure", + "waf": "Segurança" }, { "category": "Identidade", - "description": "Verifique se identidades gerenciadas atribuídas ao sistema e ao usuário distintas, dedicadas à função, com menos permissões atribuídas, sejam usadas para comunicação de serviços e aplicativos do Azure com os bancos de dados SQLDB do Azure.", + "description": "Verifique se as identidades gerenciadas atribuídas pelo sistema e pelo usuário distintas, dedicadas à função, com menos permissões atribuídas, são usadas para comunicação dos serviços e aplicativos do Azure com os bancos de dados SQLDB do Azure.", "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", "severity": "Média", "subcategory": "Azure Active Directory", - "text": "Minimizar o uso de autenticação baseada em senha para aplicativos" + "text": "Minimize o uso de autenticação baseada em senha para aplicativos", + "waf": "Segurança" }, { "category": "Identidade", - "description": "As identidades gerenciadas atribuídas pelo sistema ou pelo usuário permitem que o SQLDB do Azure se autentique em outros serviços de nuvem (por exemplo, Cofre da Chave do Azure) sem armazenar credenciais no código. Uma vez habilitadas, todas as permissões necessárias podem ser concedidas por meio do controle de acesso baseado em função do Azure para a instância SQLDB específica do Azure. Não compartilhe identidades gerenciadas atribuídas pelo usuário em vários serviços, se não for estritamente necessário.", + "description": "As identidades gerenciadas atribuídas pelo sistema ou pelo usuário permitem que o SQL do Azure se autentique em outros serviços de nuvem (por exemplo, Azure Key Vault) sem armazenar credenciais no código. Depois de habilitadas, todas as permissões necessárias podem ser concedidas por meio do controle de acesso baseado em função do Azure para a instância específica do SQL do Azure. Não compartilhe identidades gerenciadas atribuídas pelo usuário em vários serviços se não for estritamente necessário.", "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", "severity": "Baixo", "subcategory": "Identidades gerenciadas", - "text": "Atribuir ao Banco de Dados SQL do Azure uma identidade gerenciada para acesso a recursos de saída" + "text": "Atribuir ao Banco de Dados SQL do Azure uma identidade gerenciada para acesso a recursos de saída", + "waf": "Segurança" }, { "category": "Identidade", - "description": "Use uma autenticação integrada do Azure AD que elimina o uso de senhas. Os métodos de autenticação baseados em senha são uma forma mais fraca de autenticação. As credenciais podem ser comprometidas ou distribuídas por engano. Use a autenticação de logon único usando credenciais do Windows. Federar o domínio do AD local com o Azure AD e usar a autenticação integrada do Windows (para computadores ingressados no domínio com o Azure AD).", + "description": "Use uma autenticação integrada do Azure AD que elimina o uso de senhas. Os métodos de autenticação baseados em senha são uma forma mais fraca de autenticação. As credenciais podem ser comprometidas ou fornecidas por engano. Use a autenticação de logon único usando credenciais do Windows. Federe o domínio do AD local com o Azure AD e use a autenticação integrada do Windows (para computadores ingressados no domínio com o Azure AD).", "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", "severity": "Média", "subcategory": "Senhas", - "text": "Minimizar o uso de autenticação baseada em senha para usuários" + "text": "Minimize o uso de autenticação baseada em senha para usuários", + "waf": "Segurança" }, { "category": "Livro-razão", - "description": "O hash do bloco mais recente no livro-razão do banco de dados é chamado de resumo do banco de dados. Ele representa o estado de todas as tabelas contábeis no banco de dados no momento em que o bloco foi gerado. Gerar um resumo de banco de dados é eficiente, porque envolve o cálculo apenas dos hashes dos blocos que foram anexados recentemente. O Razão Confidencial do Azure é um dos armazenamentos com suporte, pode ser usado e dá suporte à geração e ao armazenamento automáticos de resumos de banco de dados. O Azure Ledger fornece recursos de segurança avançados, como a Prova de Livro-Razão Blockchain e Enclaves de Hardware Confidenciais. Use-o somente se recursos de segurança avançados forem necessários, caso contrário, reverta para o armazenamento do Azure.", + "description": "O hash do bloco mais recente no livro-razão do banco de dados é chamado de resumo do banco de dados. Ele representa o estado de todas as tabelas contábeis no banco de dados no momento em que o bloco foi gerado. A geração de um resumo do banco de dados é eficiente, pois envolve o cálculo apenas dos hashes dos blocos que foram anexados recentemente. O Razão Confidencial do Azure é um dos repositórios com suporte, pode ser usado e dá suporte à geração e armazenamento automáticos de resumos de banco de dados. O Azure Ledger fornece recursos avançados de segurança, como Blockchain Ledger Proof e Confidential Hardware Enclaves. Use-o somente se recursos avançados de segurança forem necessários, caso contrário, reverta para o armazenamento do Azure.", "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", "severity": "Média", "subcategory": "Resumo do banco de dados", - "text": "Usar o Razão Confidencial do Azure para armazenar resumos de banco de dados somente se recursos de segurança avançados forem necessários" + "text": "Usar o Razão Confidencial do Azure para armazenar resumos de banco de dados somente se recursos avançados de segurança forem necessários", + "waf": "Segurança" }, { "category": "Livro-razão", - "description": "O hash do bloco mais recente no livro-razão do banco de dados é chamado de resumo do banco de dados. Ele representa o estado de todas as tabelas contábeis no banco de dados no momento em que o bloco foi gerado. Gerar um resumo de banco de dados é eficiente, porque envolve o cálculo apenas dos hashes dos blocos que foram anexados recentemente. O recurso Armazenamento de Blobs do Azure com Armazenamento Imutável pode ser usado e dá suporte à geração e ao armazenamento automáticos de resumos de banco de dados. Para evitar a violação de seus arquivos de resumo, configure e bloqueie uma política de retenção para seu contêiner.", + "description": "O hash do bloco mais recente no livro-razão do banco de dados é chamado de resumo do banco de dados. Ele representa o estado de todas as tabelas contábeis no banco de dados no momento em que o bloco foi gerado. A geração de um resumo do banco de dados é eficiente, pois envolve o cálculo apenas dos hashes dos blocos que foram anexados recentemente. O recurso Armazenamento de Blobs do Azure com Armazenamento Imutável pode ser usado e dá suporte à geração e ao armazenamento automáticos de resumos de banco de dados. Para evitar a violação de seus arquivos de resumo, configure e bloqueie uma política de retenção para seu contêiner.", "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", "severity": "Média", "subcategory": "Resumo do banco de dados", - "text": "Se a conta de armazenamento do Azure for usada para armazenar resumos de banco de dados, verifique se a segurança está configurada corretamente" + "text": "Se a conta de armazenamento do Azure for usada para armazenar resumos de banco de dados, verifique se a segurança está configurada corretamente", + "waf": "Segurança" }, { "category": "Livro-razão", - "description": "O Ledger fornece uma forma de integridade de dados chamada integridade direta, que fornece evidências de adulteração de dados em dados em suas tabelas contábeis. O processo de verificação do banco de dados leva como entrada um ou mais resumos de banco de dados gerados anteriormente. Em seguida, ele recalcula os hashes armazenados no livro-razão do banco de dados com base no estado atual das tabelas contábeis. Se os hashes computados não corresponderem aos resumos de entrada, a verificação falhará. A falha indica que os dados foram adulterados. O processo de verificação relata todas as inconsistências que detecta.", + "description": "O Ledger fornece uma forma de integridade de dados chamada integridade direta, que fornece evidências de adulteração de dados em suas tabelas contábeis. O processo de verificação do banco de dados usa como entrada um ou mais resumos de banco de dados gerados anteriormente. Em seguida, ele recalcula os hashes armazenados no livro-razão do banco de dados com base no estado atual das tabelas do livro-razão. Se os hashes calculados não corresponderem aos resumos de entrada, a verificação falhará. A falha indica que os dados foram adulterados. O processo de verificação relata todas as inconsistências detectadas.", "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", "severity": "Média", "subcategory": "Integridade", - "text": "Agende o processo de verificação do Ledger regularmente para verificar a integridade dos dados" + "text": "Agende o processo de verificação do Ledger regularmente para verificar a integridade dos dados", + "waf": "Segurança" }, { "category": "Livro-razão", - "description": "O recurso Ledger fornece recursos de evidência de violação em seu banco de dados. Você pode atestar criptograficamente a outras partes, como auditores ou outras partes comerciais, que seus dados não foram adulterados. O Ledger ajuda a proteger os dados de qualquer invasor ou usuário com alto privilégio, incluindo administradores de banco de dados (DBAs), administradores de sistema e administradores de nuvem.", + "description": "O recurso Ledger fornece recursos de evidência de violação em seu banco de dados. Você pode atestar criptograficamente para outras partes, como auditores ou outras partes comerciais, que seus dados não foram adulterados. A Ledger ajuda a proteger os dados de qualquer invasor ou usuário de alto privilégio, incluindo administradores de banco de dados (DBAs), administradores de sistema e administradores de nuvem.", "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", "severity": "Média", "subcategory": "Livro-razão", - "text": "Se a prova criptográfica da integridade dos dados for um requisito crítico, o recurso Ledger deve ser considerado" + "text": "Se a prova criptográfica da integridade dos dados for um requisito crítico, o recurso Ledger deve ser considerado", + "waf": "Segurança" }, { "category": "Livro-razão", - "description": "Dependendo do tipo de adulteração, há casos em que você pode reparar o livro-razão sem perder dados. No artigo contido na coluna --Mais informações-, diferentes cenários e técnicas de recuperação são descritos.", + "description": "Dependendo do tipo de adulteração, há casos em que você pode reparar o livro-razão sem perder dados. No artigo contido na coluna --More Info--, são descritos diferentes cenários e técnicas de recuperação.", "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", "severity": "Média", "subcategory": "Recuperação", - "text": "Preparar um plano de resposta para investigar e reparar um banco de dados após um evento de violação" + "text": "Preparar um plano de resposta para investigar e reparar um banco de dados após um evento de violação", + "waf": "Segurança" }, { "category": "Log", - "description": "A Auditoria do Banco de Dados SQL do Azure rastreia eventos de banco de dados e os grava em um log de auditoria em sua conta de armazenamento do Azure. A auditoria ajuda você a entender a atividade do banco de dados e a obter informações sobre discrepâncias e anomalias que podem indicar preocupações comerciais ou suspeitas de violações de segurança, além de ajudá-lo a atender à conformidade normativa. Por padrão, a diretiva de auditoria inclui todas as ações (consultas, procedimentos armazenados e logons bem-sucedidos e com falha) nos bancos de dados, o que pode resultar em alto volume de logs de auditoria. É recomendável que os clientes configurem a auditoria para diferentes tipos de ações e grupos de ações usando o PowerShell.", + "description": "A Auditoria do Banco de Dados SQL do Azure rastreia eventos de banco de dados e os grava em um log de auditoria em sua conta de armazenamento do Azure. A auditoria ajuda você a entender a atividade do banco de dados e obter informações sobre discrepâncias e anomalias que podem indicar preocupações comerciais ou suspeitas de violações de segurança, além de ajudá-lo a atender à conformidade regulatória. Por padrão, a política de auditoria inclui todas as ações (consultas, procedimentos armazenados e logons bem-sucedidos e com falha) nos bancos de dados, o que pode resultar em um alto volume de logs de auditoria. É recomendável que os clientes configurem a auditoria para diferentes tipos de ações e grupos de ações usando o PowerShell.", "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "Média", "subcategory": "Auditoria", - "text": "Verifique se a Auditoria do Banco de Dados SQL do Azure está habilitada no nível do servidor" + "text": "Verifique se a Auditoria do Banco de Dados SQL do Azure está habilitada no nível do servidor", + "waf": "Segurança" }, { "category": "Log", - "description": "Os logs de Auditoria do Banco de Dados SQL do Azure podem ser gravados em contas de armazenamento externas, no espaço de trabalho do Log Analytics ou no Hub de Eventos. Certifique-se de proteger o repositório de destino usando backups e configuração segura. Use a Identidade Gerenciada do Banco de Dados SQL do Azure para acessar o armazenamento e definir um período de retenção explícito. Não conceda permissões aos administradores para o repositório de log de auditoria. Use um armazenamento de destino diferente para --Habilitando a auditoria das operações de suporte da Microsoft--. ", + "description": "Os logs de Auditoria do Banco de Dados SQL do Azure podem ser gravados em contas de armazenamento externas, workspace do Log Analytics ou Hub de Eventos. Certifique-se de proteger o repositório de destino usando backups e configuração segura. Use a Identidade Gerenciada do Banco de Dados SQL do Azure para acessar o armazenamento e definir um período de retenção explícito. Não conceda permissões aos administradores para o repositório de log de auditoria. Use um armazenamento de destino diferente para --Habilitando a auditoria de operações de suporte da Microsoft--. ", "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "Baixo", "subcategory": "Auditoria", - "text": "Verifique se os logs de Auditoria do Banco de Dados SQL do Azure são copiados e protegidos no tipo de repositório selecionado" + "text": "Verifique se os logs de Auditoria do Banco de Dados SQL do Azure são copiados e protegidos no tipo de repositório selecionado", + "waf": "Segurança" }, { "category": "Log", - "description": "O log de atividades do Azure Monitor é um log de plataforma no Azure que fornece informações sobre eventos de nível de assinatura. O registro de atividades inclui informações como quando um recurso é modificado. É recomendável enviar esse log de atividades para o mesmo repositório de armazenamento externo que o Log de Auditoria do Banco de Dados SQL do Azure (conta de armazenamento, espaço de trabalho Análise de Log, Hub de Eventos).", + "description": "O log de atividades do Azure Monitor é um log de plataforma no Azure que fornece informações sobre eventos no nível da assinatura. O log de atividades inclui informações como quando um recurso é modificado. É recomendável enviar esse log de atividades para o mesmo repositório de armazenamento externo que o Log de Auditoria do Banco de Dados SQL do Azure (conta de armazenamento, workspace do Log Analytics, Hub de Eventos).", "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "Média", "subcategory": "Auditoria", - "text": "Verifique se o Log de Atividades do Banco de Dados SQL do Azure é coletado e integrado aos logs de Auditoria" + "text": "Verifique se o Log de Atividades do Banco de Dados SQL do Azure é coletado e integrado aos logs de auditoria", + "waf": "Segurança" }, { "category": "Log", - "description": "Encaminhe todos os logs do SQL do Azure para o SIEM (Gerenciamento de Informações e Eventos de Segurança) e SOAR (Automação e Resposta de Orquestração de Segurança). Verifique se você está monitorando diferentes tipos de ativos do Azure em busca de possíveis ameaças e anomalias. Concentre-se em receber alertas de alta qualidade para reduzir os falsos positivos para os analistas classificarem. Os alertas podem ser obtidos a partir de dados de log, agentes ou outros dados.", + "description": "Encaminhe todos os logs do SQL do Azure para o SIEM (Gerenciamento de Eventos e Informações de Segurança) e o SOAR (Automação e Resposta de Orquestração de Segurança). Verifique se você está monitorando diferentes tipos de ativos do Azure em busca de possíveis ameaças e anomalias. Concentre-se em receber alertas de alta qualidade para reduzir falsos positivos para os analistas classificarem. Os alertas podem ser originados de dados de log, agentes ou outros dados.", "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", "severity": "Média", "subcategory": "SIEM/SOAR", - "text": "Verifique se os logs de Auditoria do Banco de Dados SQL do Azure estão sendo apresentados no SIEM/SOAR de suas organizações" + "text": "Verifique se os logs de auditoria do Banco de Dados SQL do Azure estão sendo apresentados ao SIEM/SOAR de suas organizações", + "waf": "Segurança" }, { "category": "Log", - "description": "Encaminhe todos os logs do SQL do Azure para o SIEM (Gerenciamento de Informações e Eventos de Segurança) e SOAR (Automação e Resposta de Orquestração de Segurança), que podem ser usados para configurar detecções de ameaças personalizadas. Verifique se você está monitorando diferentes tipos de ativos do Azure em busca de possíveis ameaças e anomalias. Concentre-se em receber alertas de alta qualidade para reduzir os falsos positivos para os analistas classificarem. Os alertas podem ser obtidos a partir de dados de log, agentes ou outros dados.", + "description": "Encaminhe todos os logs do SQL do Azure para o SIEM (Gerenciamento de Eventos e Informações de Segurança) e o SOAR (Automação e Resposta de Orquestração de Segurança), que podem ser usados para configurar detecções de ameaças personalizadas. Verifique se você está monitorando diferentes tipos de ativos do Azure em busca de possíveis ameaças e anomalias. Concentre-se em receber alertas de alta qualidade para reduzir falsos positivos para os analistas classificarem. Os alertas podem ser originados de dados de log, agentes ou outros dados.", "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "Média", "subcategory": "SIEM/SOAR", - "text": "Verifique se os dados do Log de Atividades do Banco de Dados SQL do Azure são apresentados em seu SIEM/SOAR" + "text": "Verifique se os dados do Log de Atividades do Banco de Dados SQL do Azure são apresentados no SIEM/SOAR", + "waf": "Segurança" }, { "category": "Log", - "description": "A equipe do Centro de Operações de Segurança (SOC) deve criar um plano de resposta a incidentes (manuais ou respostas manuais) para investigar e mitigar adulterações, atividades maliciosas e outros comportamentos anômalos.", + "description": "A equipe do SOC (Centro de Operações de Segurança) deve criar um plano de resposta a incidentes (guias estratégicos ou respostas manuais) para investigar e mitigar adulterações, atividades maliciosas e outros comportamentos anômalos.", "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", "severity": "Média", "subcategory": "SIEM/SOAR", - "text": "Verifique se você tem planos de resposta para eventos de log de auditoria mal-intencionados ou aberrantes" + "text": "Certifique-se de ter planos de resposta para eventos de log de auditoria mal-intencionados ou aberrantes", + "waf": "Segurança" }, { "category": "Rede", - "description": "Quando você cria um servidor lógico a partir do portal do Azure para o Banco de Dados SQL do Azure, o resultado é um ponto de extremidade público que é visível e acessível pela rede pública (Acesso Público). Em seguida, você pode limitar a conectividade com base nas regras de firewall e no Ponto de Extremidade de Serviço. Você também pode configurar a conectividade privada limitando apenas as conexões a redes internas usando o Ponto de Extremidade Privado (Acesso Privado). O Acesso Privado usando o Ponto de Extremidade Privado deve ser o padrão, a menos que se aplique um caso de negócios ou um motivo de desempenho/técnico que não possa suportá-lo. O uso de pontos de extremidade privados tem implicações de desempenho que precisam ser consideradas e avaliadas.", + "description": "Quando você cria um servidor lógico no portal do Azure para o Banco de Dados SQL do Azure, o resultado é um ponto de extremidade público visível e acessível pela rede pública (Acesso Público). Em seguida, você pode limitar a conectividade com base nas regras de firewall e no Ponto de Extremidade de Serviço. Você também pode configurar a conectividade privada limitando apenas as conexões a redes internas usando o Ponto de extremidade privado (Acesso privado). O Acesso Privado usando o Ponto de Extremidade Privado deve ser o padrão, a menos que um caso de negócios ou motivo técnico/de desempenho se aplique que não possa dar suporte a ele. O uso de pontos de extremidade privados tem implicações de desempenho que precisam ser consideradas e avaliadas.", "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "Alto", "subcategory": "Conectividade", - "text": "Revise os métodos de conectividade de Acesso Público versus Privado e selecione o apropriado para a carga de trabalho" + "text": "Examine os métodos de conectividade de Acesso Público vs. Privado e selecione o apropriado para a carga de trabalho", + "waf": "Segurança" }, { "category": "Rede", - "description": "IMPORTANTE: As conexões com o ponto de extremidade privado oferecem suporte apenas ao Proxy como a política de conexão. Ao usar pontos de extremidade privados, as conexões são intermediadas por proxy por meio do gateway do Banco de Dados SQL do Azure para os nós do banco de dados. Os clientes não terão uma conexão direta.", + "description": "IMPORTANTE: As conexões com o ponto de extremidade privado só dão suporte ao Proxy como a política de conexão. Ao usar pontos de extremidade privados, as conexões são enviadas por proxy por meio do gateway do Banco de Dados SQL do Azure para os nós do banco de dados. Os clientes não terão uma conexão direta.", "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", "severity": "Baixo", "subcategory": "Conectividade", - "text": "Manter a Política de Conexão do Banco de Dados SQL do Azure padrão se não for exigida e justificada de forma diferente" + "text": "Mantenha a Política de Conexão do Banco de Dados SQL do Azure padrão se não for necessário e justificado de forma diferente", + "waf": "Segurança" }, { "category": "Rede", - "description": "Essa opção configura o firewall para permitir todas as conexões do Azure, incluindo conexões das assinaturas de outros clientes. Se você selecionar essa opção, verifique se as permissões de login e de usuário limitam o acesso somente a usuários autorizados. Se não for estritamente necessário, mantenha essa configuração como OFF.", + "description": "Essa opção configura o firewall para permitir todas as conexões do Azure, incluindo conexões das assinaturas de outros clientes. Se você selecionar essa opção, certifique-se de que suas permissões de login e usuário limitem o acesso apenas a usuários autorizados. Se não for estritamente necessário, mantenha esta configuração como OFF.", "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "Alto", "subcategory": "Conectividade", - "text": "Verifique se a configuração Permitir que os Serviços e Recursos do Azure acessem este Servidor está desabilitada no firewall do Banco de Dados SQL do Azure" + "text": "Verifique se a configuração Permitir que serviços e recursos do Azure acessem este servidor esteja desabilitada no firewall do Banco de Dados SQL do Azure", + "waf": "Segurança" }, { "category": "Rede", - "description": "O Banco de Dados SQL do Azure tem um novo recurso interno que permite a integração nativa com pontos de extremidade REST externos. Isso significa que a integração do Banco de Dados SQL do Azure com o Azure Functions, os Aplicativos Lógicos do Azure, os Serviços Cognitivos, os Hubs de Eventos, a Grade de Eventos, os Contêineres do Azure, o Gerenciamento de API e, em geral, qualquer ponto de extremidade REST ou mesmo GraphQL. Se não for restringido corretamente, o código dentro de um banco de dados do Banco de Dados SQL do Azure poderá aproveitar esse mecanismo para exfiltrar dados. Se não for estritamente necessário, recomenda-se bloquear ou restringir esse recurso usando as Regras de Firewall de Saída.", + "description": "O Banco de Dados SQL do Azure tem um novo recurso interno que permite a integração nativa com pontos de extremidade REST externos. Isso significa que a integração do Banco de Dados SQL do Azure com Azure Functions, Aplicativos Lógicos do Azure, Serviços Cognitivos, Hubs de Eventos, Grade de Eventos, Contêineres do Azure, Gerenciamento de API e, em geral, qualquer ponto de extremidade REST ou mesmo GraphQL. Se não for restrito corretamente, o código dentro de um banco de dados do Banco de Dados SQL do Azure poderá aproveitar esse mecanismo para exfiltrar dados. Se não for estritamente necessário, é recomendável bloquear ou restringir esse recurso usando as regras de firewall de saída.", "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", "severity": "Média", "subcategory": "Controle de saída", - "text": "Bloquear ou restringir chamadas de API REST de saída para pontos de extremidade externos" + "text": "Bloquear ou restringir chamadas de API REST de saída para pontos de extremidade externos", + "waf": "Segurança" }, { "category": "Rede", "description": "As regras de firewall de saída limitam o tráfego de rede do servidor lógico do Banco de Dados SQL do Azure a uma lista definida pelo cliente de contas de Armazenamento do Azure e servidores lógicos do Banco de Dados SQL do Azure. Qualquer tentativa de acessar contas de armazenamento ou bancos de dados que não estejam nessa lista é negada.", "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", "severity": "Média", "subcategory": "Controle de saída", - "text": "Se o acesso à rede de saída for necessário, é recomendável configurar restrições de rede de saída usando o recurso de controle interno do Banco de Dados SQL do Azure" + "text": "Se o acesso à rede de saída for necessário, é recomendável configurar restrições de rede de saída usando o recurso de controle interno do Banco de Dados SQL do Azure", + "waf": "Segurança" }, { "category": "Rede", - "description": "O Ponto de Extremidade Privado é criado dentro de uma sub-rede em uma Rede Virtual do Azure. A configuração de segurança adequada deve ser aplicada também ao ambiente de rede que o contém, incluindo NSG/ASG, UDR, firewall, monitoramento e auditoria.", + "description": "O Ponto de Extremidade Privado é criado dentro de uma sub-rede em uma Rede Virtual do Azure. A configuração de segurança adequada também deve ser aplicada ao ambiente de rede que o contém, incluindo NSG/ASG, UDR, firewall, monitoramento e auditoria.", "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "Média", "subcategory": "Acesso Privado", - "text": "Se a conectividade de Acesso Privado for usada, verifique se você está usando as listas de verificação Ponto de Extremidade Privado, Rede Virtual do Azure, Firewall do Azure e Grupo de Segurança de Rede do Azure" + "text": "Se a conectividade de Acesso Privado for usada, verifique se você está usando as listas de verificação do Ponto de Extremidade Privado, da Rede Virtual do Azure, do Firewall do Azure e do Grupo de Segurança de Rede do Azure", + "waf": "Segurança" }, { "category": "Rede", - "description": "Ao adicionar uma conexão de Ponto de Extremidade Privado, o roteamento público para o servidor lógico não é bloqueado por padrão. No painel --Firewall e redes virtuais-- , a configuração --Negar acesso à rede pública-- não está selecionada por padrão. Para desabilitar o acesso à rede pública, certifique-se de selecionar --Negar acesso à rede pública--.", + "description": "Ao adicionar uma conexão de Ponto de Extremidade Privado, o roteamento público para o servidor lógico não é bloqueado por padrão. No painel --Firewall e redes virtuais-- , a configuração --Negar acesso à rede pública-- não é selecionada por padrão. Para desativar o acesso à rede pública, certifique-se de selecionar --Deny public network access--.", "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", "severity": "Alto", "subcategory": "Acesso Privado", - "text": "Se o Ponto de Extremidade Privado (Acesso Privado) for usado, considere desabilitar a conectividade do Acesso Público" + "text": "Se o Ponto de Extremidade Privado (Acesso Privado) for usado, considere desabilitar a conectividade de Acesso Público", + "waf": "Segurança" }, { "category": "Rede", - "description": "O NSG (Grupo de Segurança de Rede) e o ASG (Grupo de Segurança de Aplicativo) agora podem ser aplicados à sub-rede que contém Pontos de Extremidade Privados para restringir as conexões com o SQLDB do Azure com base em intervalos de IP de origem interna.", + "description": "O NSG (Grupo de Segurança de Rede) e o ASG (Grupo de Segurança de Aplicativo) agora podem ser aplicados à sub-rede que contém Pontos de Extremidade Privados para restringir conexões com o SQL do Azure", "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", "severity": "Média", "subcategory": "Acesso Privado", - "text": "Se o Ponto de Extremidade Privado (Acesso Privado) for usado, aplique o NSG e, eventualmente, o ASG para limitar os intervalos de endereços IP de origem de entrada" + "text": "Se o Ponto de Extremidade Privado (Acesso Privado) for usado, aplique o NSG e, eventualmente, o ASG para limitar os intervalos de endereços IP de origem de entrada", + "waf": "Segurança" }, { "category": "Rede", - "description": "Uma Instância Gerenciada (SQL MI) pode ser isolada dentro de uma rede virtual para impedir o acesso externo. Aplicativos e ferramentas que estão na mesma rede virtual ou emparelhada na mesma região podem acessá-la diretamente. Aplicativos e ferramentas que estão em regiões diferentes podem usar a conexão de rede virtual para rede virtual ou o emparelhamento de circuitos da Rota Expressa para estabelecer a conexão. O cliente deve usar NSG (Network Security Groups) e, eventualmente, firewalls internos, para restringir o acesso pela porta 1433 apenas a recursos que exijam acesso a uma instância gerenciada.", + "description": "Uma MI (Instância Gerenciada) pode ser isolada dentro de uma rede virtual para impedir o acesso externo. Aplicativos e ferramentas que estão na mesma rede virtual ou emparelhada na mesma região podem acessá-la diretamente. Aplicativos e ferramentas que estão em regiões diferentes podem usar a conexão de rede virtual para rede virtual ou o emparelhamento de circuito do ExpressRoute para estabelecer a conexão. O cliente deve usar NSG (Grupos de Segurança de Rede) e, eventualmente, firewalls internos, para restringir o acesso pela porta 1433 somente a recursos que exigem acesso a uma instância gerenciada.", "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", "severity": "Média", "subcategory": "Acesso Privado", - "text": "Aplicar NSG (Grupos de Segurança de Rede) e regras de firewall para restringir o acesso à sub-rede interna da Instância Gerenciada SQL do Azure" + "text": "Aplicar NSG (Grupos de Segurança de Rede) e regras de firewall para restringir o acesso à sub-rede interna da Instância Gerenciada de SQL do Azure", + "waf": "Segurança" }, { "category": "Rede", - "description": "O Ponto de Extremidade do Serviço de Rede Virtual do Azure é a solução preferida se você quiser estabelecer uma conexão direta com os nós de back-end do Banco de Dados SQL do Azure usando a política de Redireccionamento. Isso permitirá o acesso no modo de alto desempenho e é a abordagem recomendada do ponto de vista do desempenho.", + "description": "O Ponto de Extremidade de Serviço da Rede Virtual do Azure é a solução preferencial se você quiser estabelecer uma conexão direta com os nós de back-end do Banco de Dados SQL do Azure usando a política de redirecionamento. Isso permitirá o acesso no modo de alto desempenho e é a abordagem recomendada do ponto de vista do desempenho.", "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", "severity": "Alto", - "subcategory": "Acesso Público", - "text": "Se a conectividade de Acesso Público for usada, aproveite o Ponto de Extremidade de Serviço para restringir o acesso de Redes Virtuais do Azure selecionadas" + "subcategory": "Acesso público", + "text": "Se a conectividade de Acesso Público for usada, aproveite o Ponto de Extremidade de Serviço para restringir o acesso de Redes Virtuais do Azure selecionadas", + "waf": "Segurança" }, { "category": "Rede", "description": "O firewall do Banco de Dados SQL do Azure permite que você especifique intervalos de endereços IP dos quais as comunicações são aceitas. Essa abordagem é adequada para endereços IP estáveis que estão fora da rede privada do Azure.", "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", "severity": "Média", - "subcategory": "Acesso Público", - "text": "Se a conectividade de Acesso Público for usada, verifique se apenas IPs conhecidos específicos são adicionados ao firewall" + "subcategory": "Acesso público", + "text": "Se a conectividade de Acesso Público for usada, certifique-se de que apenas IPs conhecidos específicos sejam adicionados ao firewall", + "waf": "Segurança" }, { "category": "Rede", "description": "Recomendamos que você use regras de firewall IP no nível do banco de dados sempre que possível. Essa prática aumenta a segurança e torna seu banco de dados mais portátil. Use regras de firewall IP no nível do servidor para administradores. Use-os também quando tiver muitos bancos de dados com os mesmos requisitos de acesso e não quiser configurar cada banco de dados individualmente.", "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", "severity": "Baixo", - "subcategory": "Acesso Público", - "text": "Se a conectividade do Acesso Público for usada e controlada pelas regras de firewall do Banco de Dados SQL do Azure, use regras IP no nível do banco de dados sobre as regras IP no nível do servidor" + "subcategory": "Acesso público", + "text": "Se a conectividade de Acesso Público for usada e controlada por regras de firewall do Banco de Dados SQL do Azure, use regras de IP no nível do banco de dados no nível do servidor", + "waf": "Segurança" }, { "category": "Rede", - "description": "Uma Instância Gerenciada (SQL MI) pode ser isolada dentro de uma rede virtual para impedir o acesso externo. O ponto de extremidade público da Instância Gerenciada não está habilitado por padrão, deve ser explicitamente habilitado, somente se estritamente necessário. Se a política da empresa não permitir o uso de pontos de extremidade públicos, use a Política do Azure para impedir a habilitação de pontos de extremidade públicos em primeiro lugar.", + "description": "Uma MI (Instância Gerenciada) pode ser isolada dentro de uma rede virtual para impedir o acesso externo. O ponto de extremidade público da Instância Gerenciada não está habilitado por padrão, deve ser habilitado explicitamente, somente se estritamente necessário. Se a política da empresa não permitir o uso de pontos de extremidade públicos, use o Azure Policy para impedir a habilitação de pontos de extremidade públicos em primeiro lugar.", "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "Alto", - "subcategory": "Acesso Público", - "text": "Não habilitar o ponto de extremidade público da Instância Gerenciada SQL do Azure" + "subcategory": "Acesso público", + "text": "Não habilitar o ponto de extremidade público da Instância Gerenciada de SQL do Azure", + "waf": "Segurança" }, { "category": "Rede", - "description": "Um ponto de extremidade público de Instância Gerenciada (SQL MI) não está habilitado por padrão, deve ser explicitamente habilitado, somente se estritamente necessário. Nesse caso, recomenda-se aplicar um NSG (Network Security Groups) para restringir o acesso à porta 3342 somente a endereços IP de origem confiáveis.", + "description": "Um ponto de extremidade público de Instância Gerenciada (SQL MI) não está habilitado por padrão, deve ser habilitado explicitamente, somente se estritamente necessário. Nesse caso, é recomendável aplicar um NSG (Grupos de Segurança de Rede) para restringir o acesso à porta 3342 somente a endereços IP de origem confiáveis.", "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", "severity": "Alto", - "subcategory": "Acesso Público", - "text": "Restringir o acesso se o ponto de extremidade público da Instância Gerenciada SQL do Azure for necessário" + "subcategory": "Acesso público", + "text": "Restringir o acesso se o ponto de extremidade público da Instância Gerenciada de SQL do Azure for necessário", + "waf": "Segurança" }, { "category": "Acesso privilegiado", - "description": "A maioria das operações, suporte e solução de problemas executados pelo pessoal e subprocessadores da Microsoft não requer acesso aos dados do cliente. Nas raras circunstâncias em que esse acesso é necessário, o Customer Lockbox para Microsoft Azure fornece uma interface para que os clientes analisem e aprovem ou rejeitem solicitações de acesso a dados de clientes. Em cenários de suporte em que a Microsoft precisa acessar dados do cliente, o Banco de Dados SQL do Azure dá suporte ao Customer Lockbox para fornecer uma interface para que você revise e aprove ou rejeite solicitações de acesso a dados do cliente.", + "description": "A maioria das operações, suporte e solução de problemas executados pela equipe e subprocessadores da Microsoft não exigem acesso aos dados do cliente. Nas raras circunstâncias em que esse acesso é necessário, o Sistema de Proteção de Dados do Cliente para Microsoft Azure fornece uma interface para que os clientes revisem e aprovem ou rejeitem solicitações de acesso a dados do cliente. Em cenários de suporte em que a Microsoft precisa acessar os dados do cliente, o Banco de Dados SQL do Azure dá suporte ao Sistema de Proteção de Dados do Cliente para fornecer uma interface para você examinar e aprovar ou rejeitar solicitações de acesso aos dados do cliente.", "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", "severity": "Baixo", "subcategory": "Cofre", - "text": "Revisar e habilitar o acesso do Customer Lockbox para o Banco de Dados SQL do Azure pelo pessoal da Microsoft" + "text": "Examinar e habilitar o Sistema de Proteção de Dados do Cliente para acesso ao Banco de Dados SQL do Azure pela equipe da Microsoft", + "waf": "Segurança" }, { "category": "Acesso privilegiado", - "description": "O princípio do privilégio mínimo afirma que os usuários não devem ter mais privilégios do que o necessário para concluir suas tarefas. Os usuários de banco de dados e servidor com alto privilégio podem executar muitas atividades de configuração e manutenção no banco de dados e também podem descartar bancos de dados na instância SQL do Azure. Rastrear proprietários de bancos de dados e contas privilegiadas é importante para evitar ter permissão excessiva.", + "description": "O princípio do privilégio mínimo afirma que os usuários não devem ter mais privilégios do que o necessário para concluir suas tarefas. Os usuários de servidor e banco de dados com altos privilégios podem executar muitas atividades de configuração e manutenção no banco de dados e também podem descartar bancos de dados na instância SQL do Azure. O rastreamento de proprietários de banco de dados e contas privilegiadas é importante para evitar permissão excessiva.", "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", "severity": "Média", "subcategory": "Permissões", - "text": "Certifique-se de que os usuários recebam o nível mínimo de acesso necessário para concluir suas funções de trabalho" + "text": "Garantir que os usuários recebam o nível mínimo de acesso necessário para concluir suas funções de trabalho", + "waf": "Segurança" }, { "category": "Acesso privilegiado", - "description": "As identidades (Usuários e SPNs) devem ter o escopo da menor quantidade de acesso necessária para executar a função. Um número maior de SPNs com escopo restrito deve ser usado, em vez de ter um SPN com vários conjuntos de permissões não relacionadas. Por exemplo, se houver três aplicativos Web externos hospedados no local que fazem consultas ao Banco de Dados SQL do Azure, nem todos eles devem usar o mesmo SPN para essas atividades. Em vez disso, cada um deles deve ter seu próprio SPN de escopo rígido.", + "description": "As identidades (Usuários e SPNs) devem ter como escopo a menor quantidade de acesso necessária para executar a função. Um número maior de SPNs com escopo restrito deve ser usado, em vez de ter um SPN com vários conjuntos de permissões não relacionadas. Por exemplo, se houver três aplicativos Web externos hospedados no local que fazem consultas ao Banco de Dados SQL do Azure, nem todos deverão usar o mesmo SPN para essas atividades. Em vez disso, cada um deles deve ter seu próprio SPN com escopo restrito.", "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", "severity": "Baixo", "subcategory": "Permissões", - "text": "Verifique se aplicativos distintos receberão credenciais diferentes com permissões mínimas para acessar o Banco de Dados SQL do Azure" + "text": "Verifique se aplicativos distintos receberão credenciais diferentes com permissões mínimas para acessar o Banco de Dados SQL do Azure", + "waf": "Segurança" } ], "metadata": { - "name": "Azure SQLDB Security Checklist (Preview)" + "name": "Azure SQLDB Security Checklist (Preview)", + "state": "Preview", + "timestamp": "October 23, 2024" }, "severities": [ { @@ -506,12 +605,37 @@ "name": "Cumprido" }, { - "description": "Recomendação entendida, mas não necessária pelos requisitos atuais", + "description": "Recomendação compreendida, mas não necessária pelos requisitos atuais", "name": "Não é necessário" }, { - "description": "Não aplicável ao projeto atual", + "description": "Não aplicável para o projeto atual", "name": "N/A" } + ], + "waf": [ + { + "name": "Fiabilidade" + }, + { + "name": "Segurança" + }, + { + "name": "Custar" + }, + { + "name": "Operações" + }, + { + "name": "Desempenho" + } + ], + "yesno": [ + { + "name": "Sim" + }, + { + "name": "Não" + } ] } \ No newline at end of file diff --git a/checklists/sqldb_checklist.zh-Hant.json b/checklists/sqldb_checklist.zh-Hant.json new file mode 100644 index 00000000..d3fb4208 --- /dev/null +++ b/checklists/sqldb_checklist.zh-Hant.json @@ -0,0 +1,641 @@ +{ + "categories": [ + { + "name": "BCDR" + }, + { + "name": "辯護人" + }, + { + "name": "加密" + }, + { + "name": "身份" + }, + { + "name": "特權訪問" + }, + { + "name": "分類帳" + }, + { + "name": "伐木" + }, + { + "name": "聯網" + }, + { + "name": "數據發現和分類" + }, + { + "name": "數據掩碼" + }, + { + "name": "法典" + } + ], + "items": [ + { + "category": "BCDR", + "description": "確保您的備份免受攻擊。這應該包括對備份進行加密,以防止機密性丟失。對於常規 Azure 服務備份,備份數據將使用 Azure 平臺管理的密鑰自動加密。您還可以選擇使用客戶管理的金鑰加密備份。在這種情況下,請確保金鑰保管庫中的此客戶管理的金鑰也在備份範圍內。", + "guid": "676f6951-0368-49e9-808d-c33a692c9a64", + "id": "A01.01", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-2-encrypt-backup-data", + "severity": "中等", + "subcategory": "Azure 金鑰保管庫", + "text": "使用加密保護備份數據,並將密鑰安全地存儲在 Azure Key Vault 中", + "waf": "安全" + }, + { + "category": "BCDR", + "description": "Azure SQL 資料庫使用 SQL Server 技術每周創建一次完整備份,每 12-24 小時創建一次差異備份,每 5 到 10 分鐘創建一次事務日誌備份。默認情況下,SQL 資料庫將數據存儲在複製到配對區域的異地冗餘存儲 blob 中。", + "guid": "e2518261-b3bc-4bd1-b331-637fb2df833f", + "id": "A02.01", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#br-1-ensure-regular-automated-backups", + "severity": "中等", + "subcategory": "備份", + "text": "配置 Azure SQL 資料庫自動備份", + "waf": "安全" + }, + { + "category": "BCDR", + "description": "默認情況下,SQL 資料庫將數據存儲在複製到配對區域的異地冗餘存儲 blob 中。對於 SQL 資料庫,可以在創建資料庫時配置備份儲存冗餘,也可以為現有資料庫更新備份存儲冗餘;對現有資料庫所做的更改僅適用於將來的備份。", + "guid": "f8c7cda2-3ed7-43fb-a100-85dcd12a0ee4", + "id": "A02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/automated-backups-overview?tabs=single-database&view=azuresql#backup-storage-redundancy", + "severity": "低", + "subcategory": "備份", + "text": "啟用異地冗餘備份存儲,以防止單區域故障和數據丟失", + "waf": "安全" + }, + { + "category": "法典", + "description": "惡意代碼可能會繞過安全控制。在將自定義代碼部署到生產環境之前,必須查看正在部署的內容。使用支援原始程式碼管理的資料庫工具,如 Azure Data Studio。實施用於代碼分析、漏洞和憑據掃描的工具和邏輯。", + "guid": "7ca9f006-d2a9-4652-951c-de8e4ac5e76e", + "id": "B01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "severity": "中等", + "subcategory": "原始程式碼控制和代碼審查", + "text": "使用原始程式碼管理系統來存儲、維護和查看部署在 Azure SQLDB 資料庫中的應用程式代碼", + "waf": "安全" + }, + { + "category": "數據發現和分類", + "description": "在分類要求的情況下,Purview 是首選選項。只有在Purview不是一個選項的情況下,才使用SQL數據發現和分類。發現可能包含敏感數據的列。哪些被視為敏感數據在很大程度上取決於客戶、合規性法規等,需要由負責該數據的用戶進行評估。對列進行分類,以使用基於敏感度的高級審核和保護方案。查看自動發現的結果,並在必要時完成分類。", + "guid": "d401509b-2629-4484-9a7f-af0d29a7778f", + "id": "C01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/data-discovery-and-classification-overview?view=azuresql#faq---advanced-classification-capabilities", + "severity": "低", + "subcategory": "數據發現和分類", + "text": "規劃和配置數據發現和分類以保護敏感數據", + "waf": "安全" + }, + { + "category": "數據掩碼", + "description": "僅當列加密不是一個選項,並且有保留數據類型和格式的特定要求時,才建議使用此功能。動態數據掩碼通過向非特權用戶遮罩敏感數據來限制敏感數據的洩露。動態數據掩碼使客戶能夠指定要顯示的敏感數據量,同時對應用程式層的影響最小,從而説明防止對敏感數據進行未經授權的訪問。", + "guid": "9391fd50-135e-453e-90a7-c1a23f88cc13", + "id": "D01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/dynamic-data-masking-overview", + "severity": "低", + "subcategory": "數據掩碼", + "text": "在無法進行加密的情況下,使用 Data Masking 來防止未經授權的非管理員使用者訪問數據", + "waf": "安全" + }, + { + "category": "辯護人", + "description": "SQL 高級威脅檢測 (ATP) 提供了一個安全層,用於檢測資料庫中的潛在漏洞和異常活動,例如 SQL 注入攻擊和異常行為模式。檢測到潛在威脅時,威脅檢測會通過電子郵件和 Microsoft Defender for Cloud 發送可操作的即時警報,其中包括針對特定威脅的明確調查和修正步驟。", + "guid": "4e52d73f-5d37-428f-b3a2-e6997e835979", + "id": "E01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "severity": "高", + "subcategory": "高級威脅防護", + "text": "查看並完成高級威脅防護 (ATP) 配置", + "waf": "安全" + }, + { + "category": "辯護人", + "description": "在訂閱級別啟用 Microsoft Defender for Azure SQL,以自動載入和保護所有現有和未來的伺服器和資料庫。在訂閱級別啟用時,Azure SQL 資料庫和 Azure SQL 託管實例中的所有資料庫都將受到保護。然後,如果您願意,可以單獨禁用它們。如果要手動管理受保護的資料庫,請在訂閱級別禁用並啟用要保護的每個資料庫。", + "guid": "dff87489-9edb-4cef-bdda-86e8212b2aa1", + "id": "E02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/azure-defender-for-sql?view=azuresql#enable-microsoft-defender-for-sql ", + "severity": "高", + "subcategory": "適用於 Azure SQL 的 Defender", + "text": "啟用適用於 Azure SQL 的 Microsoft Defender", + "waf": "安全" + }, + { + "category": "辯護人", + "description": "適用於 Azure SQL ATP 的 Microsoft Defender 可檢測異常活動,這些活動指示訪問或利用資料庫的異常和可能有害的嘗試。可以配置和生成警報,並將在 Defender for Console 中報告。", + "guid": "ca342fdf-d25a-4427-b105-fcd50ff8a0ea", + "id": "E02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/threat-detection-configure", + "severity": "高", + "subcategory": "適用於 Azure SQL 的 Defender", + "text": "準備安全回應計劃以立即回應 Microsoft Defender for Azure SQL 警報", + "waf": "安全" + }, + { + "category": "辯護人", + "description": "Azure SQLDB 漏洞評估是一項提供安全狀態可見性的服務。漏洞評估包括解決安全問題和增強資料庫安全性的可行步驟。它可以幫助您監控難以跟蹤更改的動態資料庫環境,並改善您的 SQL 安全狀況。", + "guid": "a6101ae7-534c-45ab-86fd-b34c55ea21ca", + "id": "E03.01", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-overview", + "severity": "高", + "subcategory": "漏洞評估", + "text": "配置漏洞評估 (VA) 結果並查看建議", + "waf": "安全" + }, + { + "category": "辯護人", + "description": "Microsoft Defender for Cloud 為您的 Azure SQL 資料庫提供漏洞評估。漏洞評估會掃描您的資料庫以查找軟體漏洞,並提供結果清單。您可以使用這些發現來修復軟體漏洞並禁用發現結果。", + "guid": "c8c5f112-1e50-4f77-9264-8195b4cd61ac", + "id": "E03.02", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/sql-azure-vulnerability-assessment-find?view=azuresql", + "severity": "高", + "subcategory": "漏洞評估", + "text": "定期審查漏洞評估 (VA) 結果和建議,並準備修復計劃", + "waf": "安全" + }, + { + "category": "加密", + "description": "具有安全 Enclaves 的 Always Encrypted 通過啟用就地加密和更豐富的機密查詢來擴展 Always Encrypted 的機密計算功能。具有安全 Enclaves 的 Always Encrypted 透過允許在伺服器端對安全 Enclave 內的純文本數據進行某些計算來解決這些限制。如果您需要限制管理員訪問許可權,並且需要查詢支援加密列的相等匹配,則建議使用此功能。", + "guid": "65d7e54a-10a6-4094-b673-9ff3809c9277", + "id": "F01.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/encryption/always-encrypted-enclaves", + "severity": "中等", + "subcategory": "始終加密", + "text": "如果保護敏感 PII 數據免受管理員使用者的侵害是一項關鍵要求,但不能容忍列加密限制,請考慮採用具有安全 Enclaves 的 Always Encrypted", + "waf": "安全" + }, + { + "category": "加密", + "description": "借助 Azure SQL 資料庫,可以使用 Transact-SQL 對數據列應用對稱加密。此方法稱為列加密,因為您可以使用它來加密具有不同加密密鑰的特定列。這樣做可以為您提供比 TDE 更精細的加密功能,TDE 會加密頁面中的數據。使用Always Encrypted可確保敏感數據不會在 Azure SQL 資料庫或 SQL 託管實例中以純文本形式公開,即使在記憶體中/使用中也是如此。Always Encrypted 可保護數據免受資料庫管理員 (DBA) 和雲管理員(或可以冒充高特權但未經授權的使用者的不良行為者)的攻擊,並讓你能夠更好地控制誰可以訪問你的數據。", + "guid": "c03ce136-e3d5-4e17-bf25-ed955ee480d3", + "id": "F02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#control-access-of-application-users-to-sensitive-data-through-encryption", + "severity": "低", + "subcategory": "列加密", + "text": "要保護特定表列中的敏感 PII 資料免受非管理員用戶的攻擊,請考慮使用列加密", + "waf": "安全" + }, + { + "category": "加密", + "description": "透明數據加密 (TDE) 預設啟用,通過對資料庫、關聯備份和「靜態」事務日誌檔執行即時加密和解密,幫助保護資料庫檔免受信息洩露,而無需更改應用程式。", + "guid": "c614ac47-bebf-4061-b0a1-43e0c6b5e00d", + "id": "F03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-create-server", + "severity": "高", + "subcategory": "透明數據加密", + "text": "確保透明數據加密 (TDE) 保持啟用狀態", + "waf": "安全" + }, + { + "category": "加密", + "description": "如果需要在組織內管理密鑰和數據時分離職責,請利用客戶管理的密鑰 (CMK) 對 Azure SQLDB 進行透明數據加密 (TDE),並使用 Azure Key Vault 進行存儲(請參閱其清單)。當您有託管服務金鑰無法滿足的嚴格安全要求時,請利用此功能。", + "guid": "2edb4165-4f54-47cc-a891-5c82c2f21e25", + "id": "F03.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/transparent-data-encryption-byok-overview", + "severity": "中等", + "subcategory": "透明數據加密", + "text": "如果需要提高 TDE 保護的透明度和精細控制,請在 Azure Key Vault (AKV) 中使用客戶管理的金鑰 (CMK)", + "waf": "安全" + }, + { + "category": "加密", + "description": "最低傳輸層安全性 (TLS) 版本設置允許客戶選擇其 SQL 資料庫使用的 TLS 版本。可以使用 Azure 門戶、Azure PowerShell 和 Azure CLI 更改最低 TLS 版本。", + "guid": "7754b605-57fd-4bcb-8213-52c39d8e8225", + "id": "F04.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-settings?source=recommendations&view=azuresql&tabs=azure-portal#minimal-tls-version", + "severity": "高", + "subcategory": "傳輸層安全性", + "text": "將最低 TLS 版本強制實施為最新的可用版本", + "waf": "安全" + }, + { + "category": "身份", + "description": "使用 Azure Active Directory (Azure AD) 身份驗證進行集中式身份管理。僅在真正必要時使用 SQL 身份驗證,並將文檔作為例外。", + "guid": "c9b8b6bf-2c6b-453d-b400-de9a43a549d7", + "id": "G01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-overview", + "severity": "中等", + "subcategory": "Azure 活動目錄", + "text": "利用 Azure AD 身份驗證連接到 Azure SQL 資料庫", + "waf": "安全" + }, + { + "category": "身份", + "description": "使用 Azure AD 組可簡化許可權管理,並且組擁有者和資源擁有者都可以在組中添加/刪除成員。為每個邏輯伺服器的 Azure AD 管理員創建一個單獨的組。使用 Azure AD 審核活動報告監視 Azure AD 組成員身份更改。", + "guid": "29820254-1d14-4778-ae90-ff4aeba504a3", + "id": "G01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#central-management-for-identities", + "severity": "中等", + "subcategory": "Azure 活動目錄", + "text": "為每個 Azure SQL 資料庫邏輯伺服器創建一個單獨的 Azure AD 組,其中包含兩個管理員帳戶", + "waf": "安全" + }, + { + "category": "身份", + "description": "確保使用專用於函數的不同系統和使用者分配的託管標識,並分配最少的許可權,用於從 Azure 服務和應用程式到 Azure SQLDB 資料庫的通信。", + "guid": "df3a09ee-03bb-4198-8637-d141acf5f289", + "id": "G01.03", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#minimize-the-use-of-password-based-authentication-for-applications", + "severity": "中等", + "subcategory": "Azure 活動目錄", + "text": "最大限度地減少對應用程式使用基於密碼的身份驗證", + "waf": "安全" + }, + { + "category": "身份", + "description": "系統或使用者分配的託管標識使 Azure SQLDB 能夠向其他雲服務(例如 Azure Key Vault)進行身份驗證,而無需在代碼中存儲憑據。啟用后,可以通過 Azure 基於角色的訪問控制向特定 Azure SQLDB 實例授予所有必要的許可權。如果不嚴格要求,請不要在多個服務之間共用使用者分配的託管身份。", + "guid": "69891194-5074-4e30-8f69-4efc3c580900", + "id": "G02.01", + "link": "https://learn.microsoft.com/azure/active-directory/managed-identities-azure-resources/overview", + "severity": "低", + "subcategory": "託管身份", + "text": "為 Azure SQL 資料庫分配用於出站資源訪問的託管標識", + "waf": "安全" + }, + { + "category": "身份", + "description": "使用無需使用密碼的 Azure AD 集成身份驗證。基於密碼的身份驗證方法是一種較弱的身份驗證形式。憑證可能會洩露或錯誤地洩露。使用 Windows 憑據的單點登錄身份驗證。將本地 AD 域與 Azure AD 聯合,並使用整合的 Windows 身份驗證(適用於使用 Azure AD 加入域的電腦)。", + "guid": "88287d4a-8bb8-4640-ad78-03f51354d003", + "id": "G03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/authentication-aad-configure?view=azuresql&tabs=azure-powershell#active-directory-integrated-authentication", + "severity": "中等", + "subcategory": "密碼", + "text": "最大限度地減少對使用者使用基於密碼的身份驗證", + "waf": "安全" + }, + { + "category": "分類帳", + "description": "資料庫帳本中最新區塊的哈希值稱為資料庫摘要。它表示生成區塊時資料庫中所有帳本表的狀態。生成資料庫摘要是高效的,因為它只涉及計算最近附加的塊的哈希值。Azure 機密帳本是受支援的存儲之一,可以使用並支援自動生成和存儲資料庫摘要。Azure 帳本提供高級安全功能,例如區塊鏈賬本證明和機密硬體 Enclaves。僅當需要高級安全功能時才使用它,否則還原到 Azure 存儲。", + "guid": "0e853380-50ba-4bce-b2fd-5c7391c85ecc", + "id": "H01.01", + "link": "https://learn.microsoft.com/azure/architecture/guide/technology-choices/multiparty-computing-service#confidential-ledger-and-azure-blob-storage", + "severity": "中等", + "subcategory": "資料庫摘要", + "text": "僅當需要高級安全功能時,才使用 Azure 機密帳本存儲資料庫摘要", + "waf": "安全" + }, + { + "category": "分類帳", + "description": "資料庫帳本中最新區塊的哈希值稱為資料庫摘要。它表示生成區塊時資料庫中所有帳本表的狀態。生成資料庫摘要是高效的,因為它只涉及計算最近附加的塊的哈希值。可以使用具有不可變存儲功能的 Azure Blob 儲存,並支援自動生成和存儲資料庫摘要。為防止篡改摘要檔,請為容器配置並鎖定保留策略。", + "guid": "afefb2d3-95da-4ac9-acf5-33d18b32ef9a", + "id": "H01.02", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-digest-management", + "severity": "中等", + "subcategory": "資料庫摘要", + "text": "如果使用 Azure 儲存帳戶存儲資料庫摘要,請確保正確配置安全性", + "waf": "安全" + }, + { + "category": "分類帳", + "description": "Ledger 提供一種稱為正向完整性的數據完整性形式,它提供帳本表中的數據被篡改的證據。資料庫驗證過程將一個或多個以前生成的資料庫摘要作為輸入。然後,它根據帳本表的當前狀態重新計算存儲在資料庫帳本中的哈希值。如果計算的哈希值與輸入摘要不匹配,則驗證失敗。失敗表示數據已被篡改。驗證過程會報告它檢測到的所有不一致。", + "guid": "f8d4ffda-8aac-4cc6-b72b-c81cb8625420", + "id": "H02.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-database-verification", + "severity": "中等", + "subcategory": "正直", + "text": "定期安排 Ledger 驗證流程以驗證數據完整性", + "waf": "安全" + }, + { + "category": "分類帳", + "description": "Ledger 功能在您的資料庫中提供防篡改功能。您可以向其他方(例如審計師或其他業務方)加密證明您的數據未被篡改。Ledger 有助於保護數據免受任何攻擊者或高許可權用戶的攻擊,包括資料庫管理員 (DBA)、系統管理員和雲管理員。", + "guid": "2563f498-e2d3-42ea-9e7b-5517881a06a2", + "id": "H03.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-overview", + "severity": "中等", + "subcategory": "分類帳", + "text": "如果數據完整性的加密證明是一項關鍵要求,則應考慮 Ledger 功能", + "waf": "安全" + }, + { + "category": "分類帳", + "description": "根據篡改的類型,在某些情況下,您可以在不丟失數據的情況下修復帳本。在 --More Info-- 專欄中包含的文章中,介紹了不同的場景和恢復技術。", + "guid": "804fc554-6554-4842-91c1-713b32f99902", + "id": "H04.01", + "link": "https://learn.microsoft.com/sql/relational-databases/security/ledger/ledger-how-to-recover-after-tampering", + "severity": "中等", + "subcategory": "恢復", + "text": "準備響應計劃,以便在發生篡改事件後調查和修復資料庫", + "waf": "安全" + }, + { + "category": "伐木", + "description": "Azure SQL 資料庫審核會跟蹤資料庫事件並將其寫入 Azure 儲存帳戶中的審核日誌。審計可説明您了解資料庫活動,深入瞭解可能表明業務問題或可疑安全違規行為的差異和異常,並説明您滿足法規合規性要求。默認情況下,審核策略包括針對資料庫的所有操作(查詢、存儲過程以及成功和失敗的登錄),這可能會導致大量審核日誌。建議客戶使用PowerShell為不同類型的操作和操作組配置審核。", + "guid": "4082e31d-35f4-4a49-8507-d3172cc930a6", + "id": "I01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "severity": "中等", + "subcategory": "審計", + "text": "確保在伺服器級別啟用 Azure SQL 資料庫審核", + "waf": "安全" + }, + { + "category": "伐木", + "description": "Azure SQL 資料庫審核日誌可以寫入外部儲存帳戶、Log Analytics 工作區或事件中心。請務必使用備份和安全配置保護目標存儲庫。使用 Azure SQL 資料庫託管標識存取存儲並設置顯式保留期。不要向管理員授予對審計日誌存儲庫的許可權。將不同的目標儲存用於 --啟用Microsoft支援操作的審核--.", + "guid": "9b64bc50-b60f-4035-bf7a-28c4806dfb46", + "id": "I01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "severity": "低", + "subcategory": "審計", + "text": "確保在所選儲存庫類型中備份和保護 Azure SQL 資料庫審核日誌", + "waf": "安全" + }, + { + "category": "伐木", + "description": "Azure Monitor 活動日誌是 Azure 中的平臺日誌,用於深入瞭解訂閱級事件。活動日誌包括修改資源的時間等資訊。建議將此活動日誌發送到與 Azure SQL 資料庫審核日誌相同的外部存儲庫(存儲帳戶、Log Analytics 工作區、事件中心)。", + "guid": "fcd34708-87ac-4efc-aaf6-57a47f76644a", + "id": "I01.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "severity": "中等", + "subcategory": "審計", + "text": "確保收集 Azure SQL 資料庫活動日誌並將其與審核日誌集成", + "waf": "安全" + }, + { + "category": "伐木", + "description": "將 Azure SQL 中的任何日誌轉發到安全資訊和事件管理 (SIEM) 以及安全編排自動化和回應 (SOAR)。確保監視不同類型的 Azure 資產是否存在潛在威脅和異常。專注於獲取高品質的警報,以減少誤報,供分析師進行分類。警報可以來自日誌數據、代理或其他數據。", + "guid": "f96e127e-9572-453a-b325-ff89ae9f6b44", + "id": "I02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/auditing-overview", + "severity": "中等", + "subcategory": "SIEM/SOAR", + "text": "確保將 Azure SQL 資料庫審核日誌呈現給組織的 SIEM/SOAR", + "waf": "安全" + }, + { + "category": "伐木", + "description": "將 Azure SQL 中的任何日誌轉發到安全資訊和事件管理 (SIEM) 以及安全業務流程自動化和回應 (SOAR),它們可用於設置自定義威脅檢測。確保監視不同類型的 Azure 資產是否存在潛在威脅和異常。專注於獲取高品質的警報,以減少誤報,供分析師進行分類。警報可以來自日誌數據、代理或其他數據。", + "guid": "41503bf8-73da-4a10-af9f-5f7fceb5456f", + "id": "I02.02", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "severity": "中等", + "subcategory": "SIEM/SOAR", + "text": "確保將 Azure SQL 資料庫活動記錄數據呈現在 SIEM/SOAR 中", + "waf": "安全" + }, + { + "category": "伐木", + "description": "安全運營中心 (SOC) 團隊應制定事件響應計劃(playbook 或手動回應),以調查和緩解篡改、惡意活動和其他異常行為。", + "guid": "19ec7c97-c563-4e1d-82f0-54d6ec12e754", + "id": "I02.03", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "severity": "中等", + "subcategory": "SIEM/SOAR", + "text": "確保您有針對惡意或異常審計日誌記錄事件的響應計劃", + "waf": "安全" + }, + { + "category": "聯網", + "description": "從 Azure SQL 資料庫的 Azure 門戶創建邏輯伺服器時,結果是可以通過公共網路(公共訪問)看到並訪問公共終結點。然後,您可以根據防火牆規則和服務端點限制連接。您還可以配置僅私有連接,以使用私有終端節點 (Private Access) 限制與內部網路的連接。使用專用端點的專用訪問應該是預設選項,除非存在無法支援它的業務案例或性能/技術原因。使用專用終端節點會影響性能,需要考慮和評估。", + "guid": "2c6d356a-1784-475b-a42c-ec187dc8c925", + "id": "J01.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "severity": "高", + "subcategory": "連接", + "text": "查看 Public 與 Private Access 連接方法,併為工作負載選擇合適的方法", + "waf": "安全" + }, + { + "category": "聯網", + "description": "重要說明:與私有終端節點的連接僅支援 Proxy 作為連接策略。使用專用終結點時,將通過 Azure SQL 資料庫閘道代理連接到資料庫節點的連接。用戶端將沒有直接連接。", + "guid": "557b3ce5-bada-4296-8d52-a2d447bc1718", + "id": "J01.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/connectivity-architecture", + "severity": "低", + "subcategory": "連接", + "text": "保留預設的 Azure SQL 資料庫連線策略(如果沒有不同的要求和理由)", + "waf": "安全" + }, + { + "category": "聯網", + "description": "此選項將防火牆配置為允許來自 Azure 的所有連接,包括來自其他客戶訂閱的連接。如果選擇此選項,請確保您的登錄和用戶許可權僅允許授權用戶訪問。如果不是嚴格要求,請將此設置保持為 OFF。", + "guid": "f48efacf-4405-4e8d-9dd0-16c5302ed082", + "id": "J01.03", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "severity": "高", + "subcategory": "連接", + "text": "確保在 Azure SQL 資料庫防火牆中禁用「允許 Azure 服務和資源訪問此伺服器」 設置", + "waf": "安全" + }, + { + "category": "聯網", + "description": "Azure SQL 資料庫具有一項新的內置功能,允許與外部 REST 終結點進行本機集成。這意味著 Azure SQL 資料庫與 Azure Functions、Azure 邏輯應用、認知服務、事件中心、事件網格、Azure 容器、API 管理以及通常的任何 REST 甚至 GraphQL 終結點的集成。如果未適當限制,Azure SQL 資料庫資料庫中的代碼可能會利用此機制來泄露數據。如果不是嚴格要求,建議使用出站防火牆規則阻止或限制此功能。", + "guid": "cb3274a7-e36d-46f6-8de5-46d30c8dde8e", + "id": "J02.01", + "link": "https://learn.microsoft.com/sql/relational-databases/system-stored-procedures/sp-invoke-external-rest-endpoint-transact-sql", + "severity": "中等", + "subcategory": "出庫控制", + "text": "阻止或限制對外部端點的出站 REST API 調用", + "waf": "安全" + }, + { + "category": "聯網", + "description": "出站防火牆規則限制從 Azure SQL 資料庫邏輯伺服器到客戶定義的 Azure 儲存帳戶和 Azure SQL 資料庫邏輯伺服器清單的網路流量。任何訪問不在此清單中的存儲帳戶或資料庫的嘗試都將被拒絕。", + "guid": "a566dd3d-314e-4a94-9378-102c42d82b38", + "id": "J02.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/outbound-firewall-rule-overview", + "severity": "中等", + "subcategory": "出庫控制", + "text": "如果需要出站網路訪問,建議使用內置的 Azure SQL 資料庫控制功能配置出站網路限制", + "waf": "安全" + }, + { + "category": "聯網", + "description": "專用終結點是在 Azure 虛擬網路的子網中創建的。還必須對包含的網路環境應用適當的安全配置,包括 NSG/ASG、UDR、防火牆、監控和審計。", + "guid": "246cd832-f550-4af0-9c74-ca9baeeb8860", + "id": "J03.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "severity": "中等", + "subcategory": "私人訪問", + "text": "如果使用專用訪問連接,請確保使用專用終結點、Azure 虛擬網路、Azure 防火牆和 Azure 網路安全組清單", + "waf": "安全" + }, + { + "category": "聯網", + "description": "添加專用終端節點連接時,預設情況下不會阻止到邏輯伺服器的公有路由。在 --Firewall and virtual networks-- 窗格中,默認情況下未選擇設置 --Deny public network access--。要禁用公網訪問,請確保選擇 --Deny public network access--.", + "guid": "3a0808ee-ea7a-47ab-bdce-920a6a2b3881", + "id": "J03.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/private-endpoint-overview?view=azuresql#disable-public-access-to-your-logical-server", + "severity": "高", + "subcategory": "私人訪問", + "text": "如果使用私有終端節點 (Private Access),請考慮禁用 Public Access 連接", + "waf": "安全" + }, + { + "category": "聯網", + "description": "網路安全組 (NSG) 和應用程式安全組 (ASG) 現在可以應用於包含專用終結點的子網,以根據內部源 IP 範圍限制與 Azure SQLDB 的連接。", + "guid": "8600527e-e8c4-4424-90ef-1f0dca0224f2", + "id": "J03.03", + "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview#network-security-of-private-endpoints", + "severity": "中等", + "subcategory": "私人訪問", + "text": "如果使用專用終結點 (專用存取),請應用 NSG 並最終應用 ASG 以限制傳入的源 IP 位址範圍", + "waf": "安全" + }, + { + "category": "聯網", + "description": "託管實例 (SQL MI) 可以隔離在虛擬網路內部,以防止外部訪問。位於同一區域中的同一或對等虛擬網路中的應用程式和工具可以直接訪問它。位於不同區域的應用程式和工具可以使用虛擬網路到虛擬網路連接或 ExpressRoute 線路對等互連來建立連接。客戶應使用網路安全組 (NSG) 並最終使用內部防火牆,以限制通過埠 1433 的訪問,僅對需要訪問託管實例的資源進行訪問。", + "guid": "18123ef4-a0a6-45e3-87fe-7f454f65d975", + "id": "J03.04", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/connectivity-architecture-overview", + "severity": "中等", + "subcategory": "私人訪問", + "text": "應用網路安全組 (NSG) 和防火牆規則以限制對 Azure SQL 託管實例內部子網的訪問", + "waf": "安全" + }, + { + "category": "聯網", + "description": "如果要使用重定向策略建立與 Azure SQL 資料庫後端節點的直接連接,Azure 虛擬網路服務終結點是首選解決方案。這將允許在高性能模式下進行訪問,從性能角度來看,這是推薦的方法。", + "guid": "55187443-6852-4fbd-99c6-ce303597ca7f", + "id": "J04.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview?view=azuresql#ip-vs-virtual-network-firewall-rules", + "severity": "高", + "subcategory": "公共訪問", + "text": "如果使用公共訪問連接,請利用服務端點限制來自所選 Azure 虛擬網路的訪問", + "waf": "安全" + }, + { + "category": "聯網", + "description": "Azure SQL 資料庫防火牆允許您指定接受通信的IP位址範圍。此方法適用於位於 Azure 專用網路外部的穩定 IP 位址。", + "guid": "a73e32da-b3f4-4960-b5ec-2f42a557bf31", + "id": "J04.02", + "link": "https://learn.microsoft.com/azure/azure-sql/database/network-access-controls-overview", + "severity": "中等", + "subcategory": "公共訪問", + "text": "如果使用 Public Access 連接,請確保僅將特定的已知 IP 添加到防火牆", + "waf": "安全" + }, + { + "category": "聯網", + "description": "我們建議您盡可能使用資料庫級IP防火牆規則。這種做法增強了安全性,並使資料庫更具可移植性。為管理員使用伺服器級IP防火牆規則。當您有許多具有相同訪問要求的資料庫,並且您不想單獨配置每個資料庫時,也可以使用它們。", + "guid": "e0f31ac9-35c8-4bfd-9865-edb60ffc6768", + "id": "J04.03", + "link": "https://learn.microsoft.com/azure/azure-sql/database/firewall-configure", + "severity": "低", + "subcategory": "公共訪問", + "text": "如果 Azure SQL 資料庫防火牆規則使用和控制公共訪問連接,請使用資料庫級 IP 規則,而不是伺服器級 IP 規則", + "waf": "安全" + }, + { + "category": "聯網", + "description": "託管實例 (SQL MI) 可以隔離在虛擬網路內部,以防止外部訪問。默認情況下,託管實例公共終端節點未啟用,只有在嚴格需要時才必須顯式啟用。如果公司策略不允許使用公共終結點,請使用 Azure Policy 首先阻止啟用公共終結點。", + "guid": "b8435656-143e-41a8-9922-61d34edb751a", + "id": "J04.04", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "severity": "高", + "subcategory": "公共訪問", + "text": "不要啟用 Azure SQL 託管實例公共終結點", + "waf": "安全" + }, + { + "category": "聯網", + "description": "默認情況下,託管實例 (SQL MI) 公共終結點未啟用,只有在嚴格需要時,才必須顯式啟用。在這種情況下,建議應用網路安全組 (NSG),以將對埠 3342 的訪問限制為僅受信任的源 IP 位址。", + "guid": "057dd298-8726-4aa6-b590-1f81d2e30421", + "id": "J04.05", + "link": "https://learn.microsoft.com/azure/azure-sql/managed-instance/public-endpoint-overview", + "severity": "高", + "subcategory": "公共訪問", + "text": "如果需要 Azure SQL 託管實例公共終結點,請限制訪問", + "waf": "安全" + }, + { + "category": "特權訪問", + "description": "由 Microsoft 人員和子處理者執行的大多數操作、支援和故障排除不需要存取客戶數據。在需要此類訪問的極少數情況下,適用於 Microsoft Azure 的客戶密碼箱為客戶提供了一個介面,用於查看和批准或拒絕客戶數據訪問請求。 在 Microsoft 需要存取客戶資料的支援方案中,Azure SQL 資料庫支援客戶密碼箱,以便為你提供一個介面來查看和批准或拒絕客戶資料訪問請求。", + "guid": "37b6eb0f-553d-488f-8a8a-cb9bf97388ff", + "id": "K01.01", + "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "severity": "低", + "subcategory": "密碼箱", + "text": "查看並啟用 Microsoft 人員對 Azure SQL 資料庫存取的客戶密碼箱", + "waf": "安全" + }, + { + "category": "特權訪問", + "description": "最小許可權原則規定,用戶擁有的許可權不應超過完成其任務所需的許可權。高許可權資料庫和伺服器使用者可以對資料庫執行許多配置和維護活動,還可以刪除 Azure SQL 實例中的資料庫。跟蹤資料庫擁有者和特權帳戶對於避免擁有過多許可權非常重要。", + "guid": "5fe5281f-f0f9-4842-a682-8baf18bd8316", + "id": "K02.01", + "link": "https://learn.microsoft.com/azure/azure-sql/database/security-best-practice?view=azuresql#implement-principle-of-least-privilege", + "severity": "中等", + "subcategory": "權限", + "text": "確保為使用者分配完成其工作職能所需的最低訪問許可權級別", + "waf": "安全" + }, + { + "category": "特權訪問", + "description": "身份(使用者和SPN)的範圍應限定為執行該功能所需的最小訪問許可權。 應使用更多範圍嚴格的SPN,而不是使用一個具有多組不相關許可權的SPN。例如,如果本地託管了三個外部 Web 應用程式,它們對 Azure SQL 資料庫進行查詢,則它們不應都對這些活動使用相同的 SPN。 相反,它們各自都應該有自己嚴格範圍的SPN。", + "guid": "7b5b55e5-4750-4920-be97-eb726c256a5c", + "id": "K02.02", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/sql-database-security-baseline#im-3-use-azure-ad-single-sign-on-sso-for-application-access", + "severity": "低", + "subcategory": "權限", + "text": "確保為不同的應用程式分配不同的憑據,並具有訪問 Azure SQL 資料庫的最低許可權", + "waf": "安全" + } + ], + "metadata": { + "name": "Azure SQLDB Security Checklist (Preview)", + "state": "Preview", + "timestamp": "October 23, 2024" + }, + "severities": [ + { + "name": "高" + }, + { + "name": "中等" + }, + { + "name": "低" + } + ], + "status": [ + { + "description": "尚未查看此檢查", + "name": "未驗證" + }, + { + "description": "存在與此檢查關聯的操作項", + "name": "打開" + }, + { + "description": "此檢查已經過驗證,沒有與之關聯的其他操作項", + "name": "實現" + }, + { + "description": "建議已理解,但當前要求不需要", + "name": "不需要" + }, + { + "description": "不適用於當前設計", + "name": "不適用" + } + ], + "waf": [ + { + "name": "可靠性" + }, + { + "name": "安全" + }, + { + "name": "成本" + }, + { + "name": "操作" + }, + { + "name": "性能" + } + ], + "yesno": [ + { + "name": "是的" + }, + { + "name": "不" + } + ] +} \ No newline at end of file diff --git a/checklists/streamanalytics_checklist.en.json b/checklists/streamanalytics_checklist.en.json index bbc5a091..0d7089a9 100644 --- a/checklists/streamanalytics_checklist.en.json +++ b/checklists/streamanalytics_checklist.en.json @@ -1,133 +1,133 @@ { - "items": [ - { - "category": "Operations Management", - "subcategory": "High Availablity", - "text": "Leverage FTA Resiliency Handbook for Stream Analytics", - "waf": "Reliability", - "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", - "id": "41.1", - "severity": "High", - "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx" - }, - { - "category": "Operations Management", - "subcategory": "High Availablity", - "text": "Understand High Availability 99% SLA and use it to plan your DR strategy", - "description": "Azure Stream Analytics provides high availability (99.9% SLA) for jobs and clusters within a region, the details of which are transparent to the end customer. If failures occur within the service, per the documentation �Azure Stream Analytics guarantees exactly once event processing and at-least-once delivery of events, so events are never lost.�", - "waf": "Reliability", - "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", - "id": "41.2", - "severity": "Medium", - "link": "https://azure.microsoft.com/en-in/products/stream-analytics" - }, - { - "category": "Operations Management", - "subcategory": "Geo Redundancy", - "text": "Plan for Geo Redudancy of the service", - "description": "Azure Stream Analytics resources (jobs, clusters, etc.) are regional and do not provide automatic geo-failover. However, you can achieve geo-redundancy by deploying identical Stream Analytics jobs in multiple Azure regions. Each job connects to local input and output sources. It is the responsibility of your application to both send input data into the two regional inputs and reconcile between the two regional outputs.", - "waf": "Reliability", - "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", - "id": "41.3", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy" - }, - { - "category": "Operations Management", - "subcategory": "Geo Redundancy", - "text": "Depending on your availablity requirement, configure Active/Active configuration or Active/Passive configuration", - "waf": "Reliability", - "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", - "id": "41.4", - "severity": "Medium", - "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy" + "items": [ + { + "category": "Operations Management", + "subcategory": "High Availablity", + "text": "Leverage FTA Resiliency Handbook for Stream Analytics", + "waf": "Reliability", + "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", + "id": "41.1", + "severity": "High", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx" + }, + { + "category": "Operations Management", + "subcategory": "High Availablity", + "text": "Understand High Availability 99% SLA and use it to plan your DR strategy", + "description": "Azure Stream Analytics provides high availability (99.9% SLA) for jobs and clusters within a region, the details of which are transparent to the end customer. If failures occur within the service, per the documentation \ufffdAzure Stream Analytics guarantees exactly once event processing and at-least-once delivery of events, so events are never lost.\ufffd", + "waf": "Reliability", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "41.2", + "severity": "Medium", + "link": "https://azure.microsoft.com/en-in/products/stream-analytics" + }, + { + "category": "Operations Management", + "subcategory": "Geo Redundancy", + "text": "Plan for Geo Redudancy of the service", + "description": "Azure Stream Analytics resources (jobs, clusters, etc.) are regional and do not provide automatic geo-failover. However, you can achieve geo-redundancy by deploying identical Stream Analytics jobs in multiple Azure regions. Each job connects to local input and output sources. It is the responsibility of your application to both send input data into the two regional inputs and reconcile between the two regional outputs.", + "waf": "Reliability", + "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", + "id": "41.3", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy" + }, + { + "category": "Operations Management", + "subcategory": "Geo Redundancy", + "text": "Depending on your availablity requirement, configure Active/Active configuration or Active/Passive configuration", + "waf": "Reliability", + "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", + "id": "41.4", + "severity": "Medium", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy" + } + ], + "categories": [ + { + "name": "Identity and Access Management" + }, + { + "name": "Network Topology and Connectivity" + }, + { + "name": "BC and DR" + }, + { + "name": "Governance and Security" + }, + { + "name": "Cost Governance" + }, + { + "name": "Operations Management" + }, + { + "name": "Application Deployment" + } + ], + "waf": [ + { + "name": "Reliability" + }, + { + "name": "Security" + }, + { + "name": "Cost" + }, + { + "name": "Operations" + }, + { + "name": "Performance" + } + ], + "yesno": [ + { + "name": "Yes" + }, + { + "name": "No" + } + ], + "status": [ + { + "name": "Not verified", + "description": "This check has not been looked at yet" + }, + { + "name": "Open", + "description": "There is an action item associated to this check" + }, + { + "name": "Fulfilled", + "description": "This check has been verified, and there are no further action items associated to it" + }, + { + "name": "Not required", + "description": "Recommendation understood, but not needed by current requirements" + }, + { + "name": "N/A", + "description": "Not applicable for current design" + } + ], + "severities": [ + { + "name": "High" + }, + { + "name": "Medium" + }, + { + "name": "Low" + } + ], + "metadata": { + "name": "Stream Analytics Review Checklist", + "state": "Preview", + "waf": "Reliability", + "timestamp": "October 23, 2024" } - ], - "categories": [ - { - "name": "Identity and Access Management" - }, - { - "name": "Network Topology and Connectivity" - }, - { - "name": "BC and DR" - }, - { - "name": "Governance and Security" - }, - { - "name": "Cost Governance" - }, - { - "name": "Operations Management" - }, - { - "name": "Application Deployment" - } - ], - "waf": [ - { - "name": "Reliability" - }, - { - "name": "Security" - }, - { - "name": "Cost" - }, - { - "name": "Operations" - }, - { - "name": "Performance" - } - ], - "yesno": [ - { - "name": "Yes" - }, - { - "name": "No" - } - ], - "status": [ - { - "name": "Not verified", - "description": "This check has not been looked at yet" - }, - { - "name": "Open", - "description": "There is an action item associated to this check" - }, - { - "name": "Fulfilled", - "description": "This check has been verified, and there are no further action items associated to it" - }, - { - "name": "Not required", - "description": "Recommendation understood, but not needed by current requirements" - }, - { - "name": "N/A", - "description": "Not applicable for current design" - } - ], - "severities": [ - { - "name": "High" - }, - { - "name": "Medium" - }, - { - "name": "Low" - } - ], - "metadata": { - "name": "Stream Analytics Review Checklist", - "state": "Preview", - "waf": "Reliability", - "timestamp": "April 15, 2024" - } -} +} \ No newline at end of file diff --git a/checklists/streamanalytics_checklist.es.json b/checklists/streamanalytics_checklist.es.json new file mode 100644 index 00000000..cb4ae078 --- /dev/null +++ b/checklists/streamanalytics_checklist.es.json @@ -0,0 +1,133 @@ +{ + "categories": [ + { + "name": "Gestión de identidades y accesos" + }, + { + "name": "Topología de red y conectividad" + }, + { + "name": "BC y RD" + }, + { + "name": "Gobernabilidad y seguridad" + }, + { + "name": "Gobernanza de costos" + }, + { + "name": "Gestión de Operaciones" + }, + { + "name": "Implementación de aplicaciones" + } + ], + "items": [ + { + "category": "Gestión de Operaciones", + "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", + "id": "41.1", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx", + "severity": "Alto", + "subcategory": "Alta disponibilidad", + "text": "Aproveche el manual de resiliencia de FTA para Stream Analytics", + "waf": "Fiabilidad" + }, + { + "category": "Gestión de Operaciones", + "description": "Azure Stream Analytics proporciona alta disponibilidad (99,9 % de Acuerdo de Nivel de Servicio) para trabajos y clústeres dentro de una región, cuyos detalles son transparentes para el cliente final. Si se producen errores en el servicio, según la documentación, Azure Stream Analytics garantiza exactamente una vez, el procesamiento de eventos y la entrega de eventos al menos una vez, por lo que los eventos nunca se pierden.", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "41.2", + "link": "https://azure.microsoft.com/en-in/products/stream-analytics", + "severity": "Medio", + "subcategory": "Alta disponibilidad", + "text": "Comprenda el SLA de alta disponibilidad del 99 % y utilícelo para planificar su estrategia de recuperación ante desastres", + "waf": "Fiabilidad" + }, + { + "category": "Gestión de Operaciones", + "description": "Los recursos de Azure Stream Analytics (trabajos, clústeres, etc.) son regionales y no proporcionan conmutación por error geográfica automática. Sin embargo, puede lograr la redundancia geográfica mediante la implementación de trabajos idénticos de Stream Analytics en varias regiones de Azure. Cada trabajo se conecta a orígenes de entrada y salida locales. Es responsabilidad de la aplicación enviar datos de entrada a las dos entradas regionales y conciliar entre las dos salidas regionales.", + "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", + "id": "41.3", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "Medio", + "subcategory": "Redundancia geográfica", + "text": "Plan de Regulación Geográfica del servicio", + "waf": "Fiabilidad" + }, + { + "category": "Gestión de Operaciones", + "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", + "id": "41.4", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "Medio", + "subcategory": "Redundancia geográfica", + "text": "En función de los requisitos de disponibilidad, configure la configuración Activo/Activo o la configuración Activa/Pasiva", + "waf": "Fiabilidad" + } + ], + "metadata": { + "name": "Stream Analytics Review Checklist", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "Reliability" + }, + "severities": [ + { + "name": "Alto" + }, + { + "name": "Medio" + }, + { + "name": "Bajo" + } + ], + "status": [ + { + "description": "Esta comprobación aún no se ha examinado", + "name": "No verificado" + }, + { + "description": "Hay un elemento de acción asociado a esta comprobación", + "name": "Abrir" + }, + { + "description": "Esta comprobación se ha verificado y no hay más elementos de acción asociados a ella", + "name": "Cumplido" + }, + { + "description": "Recomendación comprendida, pero no necesaria por los requisitos actuales", + "name": "No es necesario" + }, + { + "description": "No aplicable para el diseño actual", + "name": "N/A" + } + ], + "waf": [ + { + "name": "Fiabilidad" + }, + { + "name": "Seguridad" + }, + { + "name": "Costar" + }, + { + "name": "Operaciones" + }, + { + "name": "Rendimiento" + } + ], + "yesno": [ + { + "name": "Sí" + }, + { + "name": "No" + } + ] +} \ No newline at end of file diff --git a/checklists/streamanalytics_checklist.ja.json b/checklists/streamanalytics_checklist.ja.json new file mode 100644 index 00000000..a62b5c3c --- /dev/null +++ b/checklists/streamanalytics_checklist.ja.json @@ -0,0 +1,133 @@ +{ + "categories": [ + { + "name": "ID およびアクセス管理" + }, + { + "name": "ネットワーク トポロジと接続性" + }, + { + "name": "BC と DR" + }, + { + "name": "ガバナンスとセキュリティ" + }, + { + "name": "コストガバナンス" + }, + { + "name": "オペレーションマネジメント" + }, + { + "name": "アプリケーションのデプロイメント" + } + ], + "items": [ + { + "category": "オペレーションマネジメント", + "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", + "id": "41.1", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx", + "severity": "高い", + "subcategory": "高い可用性", + "text": "FTA レジリエンス ハンドブックをストリーム分析に活用する", + "waf": "確実" + }, + { + "category": "オペレーションマネジメント", + "description": "Azure Stream Analytics は、リージョン内のジョブとクラスターに対して高可用性 (99.9% の SLA) を提供し、その詳細はエンド カスタマーに対して透過的です。サービス内で障害が発生した場合、Azure Stream Analytics のドキュメントによると、イベントが失われることはありません。そのため、Azure Stream Analytics では 1 回だけのイベント処理と少なくとも 1 回のイベント配信が保証されています。", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "41.2", + "link": "https://azure.microsoft.com/en-in/products/stream-analytics", + "severity": "中程度", + "subcategory": "高い可用性", + "text": "高可用性 99% SLA を理解し、それを使用して DR 戦略を計画します", + "waf": "確実" + }, + { + "category": "オペレーションマネジメント", + "description": "Azure Stream Analytics リソース (ジョブ、クラスターなど) はリージョンであり、自動 geo フェールオーバーは提供されません。ただし、地理的冗長性を実現するには、複数の Azure リージョンに同一の Stream Analytics ジョブをデプロイします。各ジョブは、ローカルの入力ソースと出力ソースに接続します。入力データを 2 つの地域入力に送信し、2 つの地域出力を調整するのは、アプリケーションの責任です。", + "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", + "id": "41.3", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "中程度", + "subcategory": "ジオ冗長性", + "text": "サービスの地理的冗長性の計画", + "waf": "確実" + }, + { + "category": "オペレーションマネジメント", + "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", + "id": "41.4", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "中程度", + "subcategory": "ジオ冗長性", + "text": "可用性の要件に応じて、アクティブ/アクティブ構成またはアクティブ/パッシブ構成を構成します", + "waf": "確実" + } + ], + "metadata": { + "name": "Stream Analytics Review Checklist", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "Reliability" + }, + "severities": [ + { + "name": "高い" + }, + { + "name": "中程度" + }, + { + "name": "低い" + } + ], + "status": [ + { + "description": "このチェックはまだ見ていません", + "name": "未確認" + }, + { + "description": "このチェックにはアクションアイテムが関連付けられています", + "name": "開ける" + }, + { + "description": "このチェックは検証済みであり、これ以上のアクション アイテムは関連付けられていません", + "name": "達成" + }, + { + "description": "推奨事項は理解されているが、現在の要件では必要ではない", + "name": "必須ではありません" + }, + { + "description": "現在のデザインには適用されません", + "name": "該当なし" + } + ], + "waf": [ + { + "name": "確実" + }, + { + "name": "安全" + }, + { + "name": "費用" + }, + { + "name": "オペレーションズ" + }, + { + "name": "パフォーマンス" + } + ], + "yesno": [ + { + "name": "はい" + }, + { + "name": "いいえ" + } + ] +} \ No newline at end of file diff --git a/checklists/streamanalytics_checklist.ko.json b/checklists/streamanalytics_checklist.ko.json new file mode 100644 index 00000000..44ff42b0 --- /dev/null +++ b/checklists/streamanalytics_checklist.ko.json @@ -0,0 +1,133 @@ +{ + "categories": [ + { + "name": "ID 및 액세스 관리" + }, + { + "name": "네트워크 토폴로지 및 연결" + }, + { + "name": "BC 및 DR" + }, + { + "name": "거버넌스 및 보안" + }, + { + "name": "비용 관리" + }, + { + "name": "운영 관리" + }, + { + "name": "응용 프로그램 배포" + } + ], + "items": [ + { + "category": "운영 관리", + "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", + "id": "41.1", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx", + "severity": "높다", + "subcategory": "높은 가용성", + "text": "스트림 분석을 위한 FTA 복원력 핸드북 활용", + "waf": "신뢰도" + }, + { + "category": "운영 관리", + "description": "Azure Stream Analytics는 지역 내의 작업 및 클러스터에 대해 고가용성(99.9% SLA)을 제공하며, 이에 대한 세부 정보는 최종 고객에게 투명합니다. 서비스 내에서 오류가 발생하는 경우 설명서에 따라 Azure Stream Analytics는 정확히 한 번의 이벤트 처리와 한 번 이상의 이벤트 배달을 보장하므로 이벤트가 손실되지 않습니다.", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "41.2", + "link": "https://azure.microsoft.com/en-in/products/stream-analytics", + "severity": "보통", + "subcategory": "높은 가용성", + "text": "고가용성 99% SLA를 이해하고 이를 사용하여 DR 전략을 계획합니다.", + "waf": "신뢰도" + }, + { + "category": "운영 관리", + "description": "Azure Stream Analytics 리소스(작업, 클러스터 등)는 지역적이며 자동 지역 장애 조치(failover)를 제공하지 않습니다. 그러나 여러 Azure 지역에 동일한 Stream Analytics 작업을 배포하여 지역 중복을 달성할 수 있습니다. 각 작업은 로컬 입력 및 출력 소스에 연결됩니다. 입력 데이터를 두 지역 입력으로 보내고 두 지역 출력 간에 조정하는 것은 응용 프로그램의 책임입니다.", + "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", + "id": "41.3", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "보통", + "subcategory": "지리적 중복성(Geo Redundancy)", + "text": "서비스의 지리적 중복 계획Plan for Geo Redudancy of the service", + "waf": "신뢰도" + }, + { + "category": "운영 관리", + "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", + "id": "41.4", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "보통", + "subcategory": "지리적 중복성(Geo Redundancy)", + "text": "가용성 요구 사항에 따라 Active/Active 구성 또는 Active/Passive 구성을 구성합니다", + "waf": "신뢰도" + } + ], + "metadata": { + "name": "Stream Analytics Review Checklist", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "Reliability" + }, + "severities": [ + { + "name": "높다" + }, + { + "name": "보통" + }, + { + "name": "낮다" + } + ], + "status": [ + { + "description": "이 검사는 아직 검토되지 않았습니다", + "name": "확인되지 않음" + }, + { + "description": "이 검사와 연관된 작업 항목이 있습니다", + "name": "열다" + }, + { + "description": "이 검사는 확인되었으며 이와 관련된 추가 작업 항목이 없습니다", + "name": "성취" + }, + { + "description": "권장 사항을 이해했지만 현재 요구 사항에 필요하지 않음", + "name": "필요 없음" + }, + { + "description": "현재 설계에는 적용되지 않습니다.", + "name": "해당 없음" + } + ], + "waf": [ + { + "name": "신뢰도" + }, + { + "name": "안전" + }, + { + "name": "비용" + }, + { + "name": "작업" + }, + { + "name": "공연" + } + ], + "yesno": [ + { + "name": "예" + }, + { + "name": "아니요" + } + ] +} \ No newline at end of file diff --git a/checklists/streamanalytics_checklist.pt.json b/checklists/streamanalytics_checklist.pt.json new file mode 100644 index 00000000..5cd3d942 --- /dev/null +++ b/checklists/streamanalytics_checklist.pt.json @@ -0,0 +1,133 @@ +{ + "categories": [ + { + "name": "Gerenciamento de identidade e acesso" + }, + { + "name": "Topologia e conectividade de rede" + }, + { + "name": "BC e DR" + }, + { + "name": "Governança e segurança" + }, + { + "name": "Governança de custos" + }, + { + "name": "Gestão de Operações" + }, + { + "name": "Implantação de aplicativos" + } + ], + "items": [ + { + "category": "Gestão de Operações", + "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", + "id": "41.1", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx", + "severity": "Alto", + "subcategory": "Alta disponibilidade", + "text": "Aproveite o Manual de Resiliência FTA para Stream Analytics", + "waf": "Fiabilidade" + }, + { + "category": "Gestão de Operações", + "description": "O Azure Stream Analytics fornece alta disponibilidade (SLA de 99,9%) para trabalhos e clusters em uma região, cujos detalhes são transparentes para o cliente final. Se ocorrerem falhas no serviço, de acordo com a documentação, o Azure Stream Analytics garante exatamente uma vez o processamento de eventos e a entrega de eventos pelo menos uma vez, para que os eventos nunca sejam perdidos.", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "41.2", + "link": "https://azure.microsoft.com/en-in/products/stream-analytics", + "severity": "Média", + "subcategory": "Alta disponibilidade", + "text": "Entenda o SLA de 99% de alta disponibilidade e use-o para planejar sua estratégia de DR", + "waf": "Fiabilidade" + }, + { + "category": "Gestão de Operações", + "description": "Os recursos do Azure Stream Analytics (trabalhos, clusters etc.) são regionais e não fornecem failover geográfico automático. No entanto, você pode obter redundância geográfica implantando trabalhos idênticos do Stream Analytics em várias regiões do Azure. Cada trabalho se conecta a fontes locais de entrada e saída. É responsabilidade do seu aplicativo enviar dados de entrada para as duas entradas regionais e reconciliar entre as duas saídas regionais.", + "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", + "id": "41.3", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "Média", + "subcategory": "Redundância geográfica", + "text": "Planejar a redundância geográfica do serviço", + "waf": "Fiabilidade" + }, + { + "category": "Gestão de Operações", + "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", + "id": "41.4", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "Média", + "subcategory": "Redundância geográfica", + "text": "Dependendo do seu requisito de disponibilidade, configure a configuração Ativa/Ativa ou a configuração Ativa/Passiva", + "waf": "Fiabilidade" + } + ], + "metadata": { + "name": "Stream Analytics Review Checklist", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "Reliability" + }, + "severities": [ + { + "name": "Alto" + }, + { + "name": "Média" + }, + { + "name": "Baixo" + } + ], + "status": [ + { + "description": "Esta verificação ainda não foi analisada", + "name": "Não verificado" + }, + { + "description": "Há um item de ação associado a essa verificação", + "name": "Abrir" + }, + { + "description": "Essa verificação foi verificada e não há mais itens de ação associados a ela", + "name": "Cumprido" + }, + { + "description": "Recomendação compreendida, mas não necessária pelos requisitos atuais", + "name": "Não é necessário" + }, + { + "description": "Não aplicável para o projeto atual", + "name": "N/A" + } + ], + "waf": [ + { + "name": "Fiabilidade" + }, + { + "name": "Segurança" + }, + { + "name": "Custar" + }, + { + "name": "Operações" + }, + { + "name": "Desempenho" + } + ], + "yesno": [ + { + "name": "Sim" + }, + { + "name": "Não" + } + ] +} \ No newline at end of file diff --git a/checklists/streamanalytics_checklist.zh-Hant.json b/checklists/streamanalytics_checklist.zh-Hant.json new file mode 100644 index 00000000..0af5526a --- /dev/null +++ b/checklists/streamanalytics_checklist.zh-Hant.json @@ -0,0 +1,133 @@ +{ + "categories": [ + { + "name": "身份和訪問管理" + }, + { + "name": "網路拓撲和連接" + }, + { + "name": "BC 和DR" + }, + { + "name": "治理和安全" + }, + { + "name": "成本治理" + }, + { + "name": "運營管理" + }, + { + "name": "應用程式部署" + } + ], + "items": [ + { + "category": "運營管理", + "guid": "32e52e36-11c8-418b-8a0b-c511e43a18a9", + "id": "41.1", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-stream_analytics_v1.docx", + "severity": "高", + "subcategory": "高可用性", + "text": "利用 FTA 彈性手冊進行流分析", + "waf": "可靠性" + }, + { + "category": "運營管理", + "description": "Azure 流分析為區域內的作業和群集提供高可用性 (99.9% SLA),其詳細資訊對最終客戶是透明的。如果服務中發生故障,根據文檔,Azure 流分析保證事件處理僅一次,並且至少傳遞一次事件,因此事件永遠不會丟失。", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "id": "41.2", + "link": "https://azure.microsoft.com/en-in/products/stream-analytics", + "severity": "中等", + "subcategory": "高可用性", + "text": "瞭解高可用性 99% SLA 並使用它來規劃 DR 策略", + "waf": "可靠性" + }, + { + "category": "運營管理", + "description": "Azure 流分析資源(作業、群集等)是區域性的,不提供自動異地故障轉移。但是,可以通過在多個 Azure 區域中部署相同的流分析作業來實現異地冗餘。每個作業都連接到本地輸入和輸出源。您的應用程式負責將輸入資料發送到兩個區域輸入,並在兩個區域輸出之間進行協調。", + "guid": "fc833934-8b26-42d6-ac5f-512925498e6d", + "id": "41.3", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "中等", + "subcategory": "異地冗餘", + "text": "規劃服務的 Geo Redudancy", + "waf": "可靠性" + }, + { + "category": "運營管理", + "guid": "b9d37dac-43bc-46cd-8d7a-a9b24604489a", + "id": "41.4", + "link": "https://learn.microsoft.com/azure/stream-analytics/geo-redundancy", + "severity": "中等", + "subcategory": "異地冗餘", + "text": "根據您的可用性要求,配置主動/主動配置或主動/被動配置", + "waf": "可靠性" + } + ], + "metadata": { + "name": "Stream Analytics Review Checklist", + "state": "Preview", + "timestamp": "October 23, 2024", + "waf": "Reliability" + }, + "severities": [ + { + "name": "高" + }, + { + "name": "中等" + }, + { + "name": "低" + } + ], + "status": [ + { + "description": "尚未查看此檢查", + "name": "未驗證" + }, + { + "description": "存在與此檢查關聯的操作項", + "name": "打開" + }, + { + "description": "此檢查已經過驗證,沒有與之關聯的其他操作項", + "name": "實現" + }, + { + "description": "建議已理解,但當前要求不需要", + "name": "不需要" + }, + { + "description": "不適用於當前設計", + "name": "不適用" + } + ], + "waf": [ + { + "name": "可靠性" + }, + { + "name": "安全" + }, + { + "name": "成本" + }, + { + "name": "操作" + }, + { + "name": "性能" + } + ], + "yesno": [ + { + "name": "是的" + }, + { + "name": "不" + } + ] +} \ No newline at end of file diff --git a/checklists/waf_checklist.en.json b/checklists/waf_checklist.en.json index 5290d06e..35bf4189 100644 --- a/checklists/waf_checklist.en.json +++ b/checklists/waf_checklist.en.json @@ -1,5 +1,207 @@ { "items": [ + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "High", + "text": "Disable Azure Container Registry image export", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "High", + "text": "Enable Azure Policies for Azure Container Registry", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "High", + "text": "Sign and Verify containers with notation (Notary v2)", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "Medium", + "text": "Encrypt registry with a customer managed key", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "High", + "text": "Use Managed Identities to connect instead of Service Principals", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "High", + "text": "Disable local authentication for management plane access", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "High", + "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable anonymous pull/push access", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "Medium", + "text": "Disable Anonymous pull access", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "High", + "text": "Disable repository-scoped access tokens", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "High", + "text": "Deploy images from a trusted environment", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "Medium", + "text": "Disable Azure ARM audience tokens for authentication", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "Medium", + "text": "Enable diagnostics logging", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "Medium", + "text": "Control inbound network access with Private Link", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Disable public network access if inbound network access is secured using Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "Medium", + "text": "Disable Public Network access", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Only the ACR Premium SKU supports Private Link access", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "Medium", + "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "Low", + "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "severity": "Medium", + "text": "Deploy validated container images", + "waf": "Security" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "High", + "text": "Use up-to-date platforms, languages, protocols and frameworks", + "waf": "Security" + }, { "arm-service": "Microsoft.App/containerApps", "checklist": "Container Apps Review", @@ -3647,46 +3849,6 @@ "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Cost" }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "High", - "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", - "severity": "Medium", - "text": "Configure data persistence for an Azure Cache for Redis instance. Because your cache data is stored in memory, a rare and unplanned failure of multiple nodes can cause all the data to be dropped. To avoid losing data completely, Redis persistence allows you to take periodic snapshots of in-memory data, and store it to your storage account.", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", - "severity": "Medium", - "text": "Use Geo-redundant storage account to persist Azure Cache for Redis data, or zonally redundant where geo-redundancy is not available", - "waf": "Reliability" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", - "severity": "Medium", - "text": "Configure passive geo-replication for Premium Azure Cache for Redis instances. Geo-replication is a mechanism for linking two or more Azure Cache for Redis instances, typically spanning two Azure regions. Geo-replication is designed mainly for cross-region disaster recovery. Two Premium tier cache instances are connected through geo-replication in a way that provides reads and writes to your primary cache, and that data is replicated to the secondary cache.", - "waf": "Reliability" - }, { "arm-service": "microsoft.network/frontdoors", "checklist": "Azure Application Delivery Networking", @@ -6026,208 +6188,6 @@ "text": "Consider using dedicated model deployments per consumer group to provide per-model usage isolation that can help prevent noisy neighbors between your consumer groups", "waf": "Operational Excellence" }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable image export to prevent data exfiltration. Note that this will prevent image import of images into another ACR instance.", - "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", - "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", - "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", - "service": "ACR", - "severity": "High", - "text": "Disable Azure Container Registry image export", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", - "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", - "service": "ACR", - "severity": "High", - "text": "Enable Azure Policies for Azure Container Registry", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "The Azure Key Vault (AKV) is used to store a signing key that can be utilized by?notation?with the notation AKV plugin (azure-kv) to sign and verify container images and other artifacts. The Azure Container Registry (ACR) allows you to attach these signatures using the?az?or?oras?CLI commands.", - "guid": "d345293c-7639-4637-a551-c5c04e401955", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", - "service": "ACR", - "severity": "High", - "text": "Sign and Verify containers with notation (Notary v2)", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Container Registry automatically encrypts images and other artifacts that you store. By default, Azure automatically encrypts the registry content at rest by using service-managed keys. By using a customer-managed key, you can supplement default encryption with an additional encryption layer.", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", - "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", - "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", - "service": "ACR", - "severity": "Medium", - "text": "Encrypt registry with a customer managed key", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Use managed identities to secure ACRPull/Push RBAC access from client applications", - "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "service": "ACR", - "severity": "High", - "text": "Use Managed Identities to connect instead of Service Principals", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "The local Administrator account is disabled by default and should not be enabled. Use either Token or RBAC-based access methods instead", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "guid": "be0e38ce-e297-411b-b363-caaab79b198d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", - "service": "ACR", - "severity": "High", - "text": "Disable local authentication for management plane access", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable Administrator account and assign RBAC roles to principals for ACR Pull/Push operations", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", - "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", - "service": "ACR", - "severity": "High", - "text": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable anonymous pull/push access", - "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", - "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", - "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", - "service": "ACR", - "severity": "Medium", - "text": "Disable Anonymous pull access", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Token authentication doesn't support assignment to an AAD principal. Any tokens provided are able to be used by anyone who can access the token", - "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", - "service": "ACR", - "severity": "High", - "text": "Disable repository-scoped access tokens", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy container images to an ACR behind a Private endpoint within a trusted network", - "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", - "service": "ACR", - "severity": "High", - "text": "Deploy images from a trusted environment", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Only tokens with an ACR audience can be used for authentication. Used when enabling Conditional access policies for ACR", - "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", - "service": "ACR", - "severity": "Medium", - "text": "Disable Azure ARM audience tokens for authentication", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Set up a diagnostic setting to send 'repositoryEvents' & 'LoginEvents' to Log Analytics as the central destination for logging and monitoring. This allows you to monitor control plane activity on the ACR resource itself.", - "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", - "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", - "service": "ACR", - "severity": "Medium", - "text": "Enable diagnostics logging", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch", - "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", - "service": "ACR", - "severity": "Medium", - "text": "Control inbound network access with Private Link", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Disable public network access if inbound network access is secured using Private Link", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", - "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", - "service": "ACR", - "severity": "Medium", - "text": "Disable Public Network access", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Only the ACR Premium SKU supports Private Link access", - "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", - "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", - "service": "ACR", - "severity": "Medium", - "text": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU)", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Azure Defender for containers or equivalent service should be used to scan container images for vulnerabilities", - "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", - "service": "ACR", - "severity": "Low", - "text": "Enable Defender for Containers to scan Azure Container Registry for vulnerabilities", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Deploy trusted code that was validated and scanned for vulnerabilities according to DevSecOps practices.", - "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", - "service": "ACR", - "severity": "Medium", - "text": "Deploy validated container images", - "waf": "Security" - }, - { - "arm-service": "microsoft.containerregistry/registries", - "checklist": "Azure Container Registry Security Review", - "description": "Use the latest versions of supported platforms, programming languages, protocols, and frameworks.", - "guid": "4e401955-387e-45ce-b126-cd132af5b20c", - "service": "ACR", - "severity": "High", - "text": "Use up-to-date platforms, languages, protocols and frameworks", - "waf": "Security" - }, { "arm-service": "Microsoft.Kusto/clusters", "checklist": "Azure Data Explorer Review Checklist", @@ -6408,6 +6368,46 @@ "text": "If using Keyvault integration, use SLA of Keyvault to understand your availablity", "waf": "Reliability" }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "High", + "text": "Enable zone redundancy for Azure Cache for Redis. Azure Cache for Redis supports zone redundant configurations in the Premium and Enterprise tiers. A zone redundant cache can place its nodes across different Azure Availability Zones in the same region. It eliminates data center or AZ outage as a single point of failure and increases the overall availability of your cache.", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "Medium", + "text": "Configure data persistence for an Azure Cache for Redis instance. Because your cache data is stored in memory, a rare and unplanned failure of multiple nodes can cause all the data to be dropped. To avoid losing data completely, Redis persistence allows you to take periodic snapshots of in-memory data, and store it to your storage account.", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "Medium", + "text": "Use Geo-redundant storage account to persist Azure Cache for Redis data, or zonally redundant where geo-redundancy is not available", + "waf": "Reliability" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "Medium", + "text": "Configure passive geo-replication for Premium Azure Cache for Redis instances. Geo-replication is a mechanism for linking two or more Azure Cache for Redis instances, typically spanning two Azure regions. Geo-replication is designed mainly for cross-region disaster recovery. Two Premium tier cache instances are connected through geo-replication in a way that provides reads and writes to your primary cache, and that data is replicated to the secondary cache.", + "waf": "Reliability" + }, { "arm-service": "Microsoft.AVS/privateClouds", "checklist": "Azure VMware Solution Design Review", @@ -7376,6 +7376,7 @@ "description": "Azure Event Hub provides encryption of data at rest. If you use your own key, the data is still encrypted using the Microsoft-managed key, but in addition the Microsoft-managed key will be encrypted using the customer-managed key. ", "guid": "7aaf12e7-b94e-4f6e-847d-2d92981b1cd6", "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend SkuName = tostring(sku.name) | extend EncryptionEnabled = iif(isnotempty(properties.encryption.keySource), 'Enabled', 'Disabled') | extend compliant = iif(EncryptionEnabled == 'Enabled', true, false) | project name, resourceGroup, location, SkuName, EncryptionEnabled, compliant | where SkuName == 'Premium'", "service": "Event Hubs", "severity": "Low", "text": "Use customer-managed key option in data at rest encryption when required", @@ -7388,6 +7389,7 @@ "description": "Azure Event Hubs namespaces permit clients to send and receive data with TLS 1.0 and above. To enforce stricter security measures, you can configure your Event Hubs namespace to require that clients send and receive data with a newer version of TLS. If an Event Hubs namespace requires a minimum version of TLS, then any requests made with an older version will fail. ", "guid": "d2f54b29-769e-43a6-a0e7-828ac936657e", "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend MinimumTlsVersion = tostring(properties.minimumTlsVersion) | extend compliant = iif(MinimumTlsVersion == '1.2' or MinimumTlsVersion == '1.3', true, false) | project name, resourceGroup, location, MinimumTlsVersion, compliant", "service": "Event Hubs", "severity": "Medium", "text": "Enforce a minimum required version of Transport Layer Security (TLS) for requests ", @@ -7482,6 +7484,7 @@ "description": " This will be turned on automatically for a new EH namespace created from the portal with Premium, Dedicated, or Standard SKUs in a zone-enabled region. Both the EH metadata and the event data itself are replicated across zones", "guid": "f15bce21-9e4a-40eb-9787-9424d226786d", "link": "https://learn.microsoft.com/azure/event-hubs/event-hubs-premium-overview#high-availability-with-availability-zones", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend zoneRedundant = tobool(properties.zoneRedundant) | extend compliant = iff(zoneRedundant == true, true, false) | project name, resourceGroup, zoneRedundant, compliant", "service": "Event Hubs", "severity": "High", "text": "Leverage Availability Zones if regionally applicable", @@ -7492,6 +7495,7 @@ "checklist": "Azure Event Hub Review", "guid": "20b56c56-ad58-4519-8f82-735c586bb281", "link": "https://learn.microsoft.com/azure/event-hubs/compare-tiers", + "query": "resources | where type =~ 'Microsoft.EventHub/namespaces' | extend sku = tostring(sku.name) | extend compliant = iff(sku == 'Premium', true, false) | project name, resourceGroup, location, sku, compliant", "service": "Event Hubs", "severity": "Medium", "text": "Use the Premium or Dedicated SKUs for predicable performance", @@ -7923,6 +7927,17 @@ "text": "Restrict use of local users on sql workloads on Synapse", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No additional configurations are required as this is enabled on a default deployment.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Encrypt sensitive data in transit", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7934,6 +7949,15 @@ "text": "Use managed identity to authenticate to the services", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Enable data at rest encryption by default", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7944,6 +7968,17 @@ "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Keyvaults to store your CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Use customer-managed key option in data at rest encryption when required", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7976,6 +8011,16 @@ "text": "Use managed vnet workspace to restrict the access over public internet", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Microsoft Entra ID as the default authentication method.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "severity": "High", + "text": "Use Microsoft Entra ID as the default authentication method and disable local access wherever possible", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7987,6 +8032,16 @@ "text": "Configure private endpoints to connect to the external services and disable public access", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Microsoft Entra ID as the default authentication method.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Use managed identity to authenticate to the services", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7997,6 +8052,15 @@ "text": "If enabling public access highly recommended to configure IP firewall rules", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Configure conditional access policies to restrict the access on Data plane", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8007,6 +8071,16 @@ "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn�t leave your corporate network", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Restrict exposure of keys and secerts", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "severity": "High", + "text": "Use Azure Key Vaults to store secrets and crendentials.", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8018,6 +8092,37 @@ "text": "Enable Data Exfiltration Protection (DEP)", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "severity": "High", + "text": "Separate and limit highly privileged/administrative users", + "waf": "Security" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "When you create an Event Hubs namespace, a policy rule named RootManageSharedAccessKey is automatically created for the namespace. This policy has manage permissions for the entire namespace. It�s recommended that you treat this rule like an administrative root account and don�t use it in your application. You can create additional policy rules in the Configure tab for the namespace in the portal, via PowerShell or Azure CLI. Avoid the usage of local authentication methods or accounts, these should be disabled wherever possible. Instead use Azure AD to authenticate where possible.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Authenticate access to Event Hubs resources using shared access signatures (SAS) and restrict local users", + "waf": "Security" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use Azure role-based access control (Azure RBAC) to manage Azure resource access through built-in role assignments. Azure RBAC roles can be assigned to users, groups, service principals, and managed identities.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Use Azure RBACs to fine grain the access ", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8029,6 +8134,16 @@ "text": "Data Encryption at rest using Customer managed Keys for workspace", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Service supports disabling public network access either through using service-level IP ACL filtering rule (not NSG or Azure Firewall) or using a 'Disable Public Network Access' toggle switch.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Disable Public Network Access", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8040,6 +8155,15 @@ "text": "Data Encryption in transit ", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Use Vnets to isolate traffic over restricted network ", + "waf": "Security" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8050,6 +8174,16 @@ "text": "Store passwords, secerts and keys in Azure key vault", "waf": "Security" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "Medium", + "text": "Deploy private endpoints for all Azure resources that support the Private Link feature, to establish a private access point for the resources.", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8061,6 +8195,90 @@ "text": "Use Azure Key Vault secrets in pipeline activities", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric controls data access using workspaces. In workspaces, data appears in the form of Fabric items, and users can't view or use items (data) unless you give them access to the workspace. You can find more information about workspace and item permissions, in Permission model.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use Workspace roles to provide access to the users on the data", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "OneLake RBAC uses role assignments to apply permissions to its members.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use RBAC on Onelake to provide fine grain access on the data in Tables/Files Onelake ", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Take into account the access of the user at both target and source location of the shortcut", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "When using shortcuts the user identity of the user should have access on the target location of the shortcut as well", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Not all users need to have access on the entire workspace using roles so instead restrict giving roles on the entire workspace and only share the item to the user using share item feature or managing permission in Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Restrict providing workspace level role to users instead share an item only to the users", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use features like RLS, CLS and Dynamic data masking to enhance your data security requirements on sql workloads.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Limit access to the data by defining RLS, CLS and dynamic data masking on Warehouse and SQL analytics endpoints", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use features like RLS and OLS on Power BI to have more security features on semantic models", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Limit access to the data by defining RLS and OLS on semantic models in Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "In Fabric, all data that is stored in OneLake is encrypted at rest", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Encrypt Data at rest", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Data in transit across the public internet between Microsoft services is always encrypted with at least TLS 1.2. Fabric negotiates to TLS 1.3 whenever possible.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Encrypt data in transit", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8071,6 +8289,16 @@ "text": "Restrict use of local users whereever necessary", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No need to do anything. Every request to connect to Fabric is authenticated with Microsoft Entra ID, allowing users to safely connect to Fabric from their corporate office, when working at home, or from a remote location.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use Microsoft Entra ID as default authentication method", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8082,6 +8310,16 @@ "text": "Use managed identity to authenticate to the services", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "A Fabric workspace identity is an automatically managed service principal that can be associated with a Fabric workspace. Workspace identities can be created in the workspace settings of any workspace except My workspaces. A workspace identity is automatically assigned the workspace contributor role and has access to workspace items. Limitation: Write to shortcut destination fails when using workspace identity as the authentication method. Connections with workspace-identity-authentication can only be used in Onelake shortcuts and data pipelines.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use workspace identity to authenticate to the services", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8092,6 +8330,16 @@ "text": "Separate and limit highly privileged/administrative users and enable MFA and conditional policies", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Grant the identity permissions on the storage account", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Provide RBAC roles on storage account to the managed identity to make a successful connection", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8101,6 +8349,16 @@ "text": "Disable access over public internet and configure either firewall rules or trusted services rules", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric workspaces with a workspace identity can securely read or write to firewall-enabled Azure Data Lake Storage Gen2 accounts through�trusted workspace access�for OneLake shortcuts.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure trusted workspace access to access storage account behind firewall ", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8110,6 +8368,17 @@ "text": "Deploy SHIR VMs in your vnet if you are working with sensitive data that shouldn�t leave your corporate network", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Managed virtual networks are virtual networks that are created and managed by Microsoft Fabric for each Fabric workspace. Managed virtual networks provide network isolation for Fabric Spark workloads, meaning that the compute clusters are deployed in a dedicated network and are no longer part of the shared virtual network. It is only supported for spark workload in Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Use managed vnet option if you have network isolation needs", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8120,6 +8389,17 @@ "text": "Use managed vnet IR to restrict the access over public internet for Azure Integration Runtime", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Managed private endpoints are feature that allows secure and private access to data sources from Fabric Spark workloads. You cannot use starter pool with managed PE", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure managed private endpoints to access Azure services", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8131,6 +8411,71 @@ "text": "Configure managed private endpoints to connect to resources using managed azure IR", "waf": "Security" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric uses a private IP address from your virtual network. The endpoint allows users in your network to communicate with Fabric over the private IP address using private links.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure Private Links to access resources in your own Azure vnet i.e traffic coming in your Fabric environment", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "When a user authenticates access is determined based on a set of policies that might include IP address, location, and managed devices.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure Microsoft Entra ID conditional access if a user is trying to access your Fabric environment", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "In Azure, a service tag is a defined group of IP addresses that is automatically managed, as a group, to minimize the complexity of updates or changes to network security rules.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "You can use Azure service tags to enable connections to and from Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "optional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "You can add Fabric URLs to your allowlist", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "optional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "You can add Power BI URLs to your allowlist", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Security" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "The data gateway lets you connect your Azure and other data services to Microsoft Fabric and the Power Platform to securely communicate with the data source, execute queries, and transmit results back to the service.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "Medium", + "text": "Configure and use On-prem data gateway or Vnet data gateway to connect to sources either on prem or behind a virtual network", + "waf": "Security" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -11916,7 +12261,7 @@ ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/waf_checklist.es.json b/checklists/waf_checklist.es.json index 4ae10997..331083d0 100644 --- a/checklists/waf_checklist.es.json +++ b/checklists/waf_checklist.es.json @@ -1,5 +1,373 @@ { "items": [ + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Aplicación de las instrucciones de la prueba comparativa de seguridad en la nube de Microsoft relacionadas con el almacenamiento", + "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", + "service": "Azure Storage", + "severity": "Medio", + "text": "Tenga en cuenta la \"línea base de seguridad de Azure para el almacenamiento\"", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "De forma predeterminada, Azure Storage tiene una dirección IP pública y es accesible desde Internet. Los puntos de conexión privados permiten exponer de forma segura Azure Storage solo a los recursos de proceso de Azure que necesitan acceso, lo que elimina la exposición a la Internet pública", + "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", + "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere la posibilidad de usar puntos de conexión privados para Azure Storage", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Las cuentas de almacenamiento recién creadas se crean mediante el modelo de implementación de ARM, de modo que RBAC, auditoría, etc. están habilitados. Asegúrese de que no hay cuentas de almacenamiento antiguas con el modelo de implementación clásica en una suscripción", + "guid": "30e37c3e-2971-41b2-963c-eee079b598de", + "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", + "service": "Azure Storage", + "severity": "Medio", + "text": "Asegúrese de que las cuentas de almacenamiento más antiguas no usan el \"modelo de implementación clásica\"", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Aproveche Microsoft Defender para obtener información sobre la actividad sospechosa y los errores de configuración.", + "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", + "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", + "service": "Azure Storage", + "severity": "Alto", + "text": "Habilitación de Microsoft Defender para todas las cuentas de almacenamiento", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "El mecanismo de eliminación temporal permite recuperar blobs eliminados accidentalmente.", + "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", + "service": "Azure Storage", + "severity": "Medio", + "text": "Habilitación de la \"eliminación temporal\" para blobs", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere la posibilidad de deshabilitar de forma selectiva la \"eliminación temporal\" para determinados contenedores de blobs, por ejemplo, si la aplicación debe asegurarse de que la información eliminada se elimina inmediatamente, por ejemplo, por motivos de confidencialidad, privacidad o cumplimiento. ", + "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "service": "Azure Storage", + "severity": "Medio", + "text": "Deshabilitación de la \"eliminación temporal\" de blobs", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "La eliminación temporal de contenedores permite recuperar un contenedor después de que se haya eliminado, por ejemplo, recuperarse de una operación de eliminación accidental.", + "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", + "service": "Azure Storage", + "severity": "Alto", + "text": "Habilitación de la \"eliminación temporal\" para los contenedores", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere la posibilidad de deshabilitar de forma selectiva la \"eliminación temporal\" para determinados contenedores de blobs, por ejemplo, si la aplicación debe asegurarse de que la información eliminada se elimina inmediatamente, por ejemplo, por motivos de confidencialidad, privacidad o cumplimiento. ", + "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "service": "Azure Storage", + "severity": "Medio", + "text": "Deshabilitación de la \"eliminación temporal\" para contenedores", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Evita la eliminación accidental de una cuenta de almacenamiento, obligando al usuario a quitar primero el bloqueo de eliminación, antes de la eliminación", + "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "service": "Azure Storage", + "severity": "Alto", + "text": "Habilitación de bloqueos de recursos en cuentas de almacenamiento", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere la posibilidad de aplicar directivas de \"retención legal\" o \"retención basada en el tiempo\" para los blobs, de modo que sea imposible eliminar el blob, el contenedor o la cuenta de almacenamiento. Tenga en cuenta que 'imposible' en realidad significa 'imposible'; una vez que una cuenta de almacenamiento contiene un blob inmutable, la única manera de \"deshacerse\" de esa cuenta de almacenamiento es cancelando la suscripción de Azure.", + "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", + "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere la posibilidad de blobs inmutables", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere la posibilidad de deshabilitar el acceso HTTP/80 sin protección a la cuenta de almacenamiento, de modo que todas las transferencias de datos estén cifradas, protegidas por integridad y el servidor esté autenticado. ", + "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Azure Storage", + "severity": "Alto", + "text": "Requerir HTTPS, es decir, deshabilitar el puerto 80 en la cuenta de almacenamiento", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Al configurar un dominio personalizado (nombre de host) en una cuenta de almacenamiento, compruebe si necesita TLS/HTTPS; si es así, es posible que tenga que colocar Azure CDN delante de la cuenta de almacenamiento.", + "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", + "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", + "service": "Azure Storage", + "severity": "Alto", + "text": "Al aplicar HTTPS (deshabilitar HTTP), compruebe que no usa dominios personalizados (CNAME) para la cuenta de almacenamiento.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Requerir HTTPS cuando un cliente usa un token de SAS para acceder a los datos de blobs ayuda a minimizar el riesgo de pérdida de credenciales.", + "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", + "service": "Azure Storage", + "severity": "Medio", + "text": "Limitar los tokens de firma de acceso compartido (SAS) solo a las conexiones HTTPS", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Los tokens de AAD deben favorecerse sobre las firmas de acceso compartido, siempre que sea posible", + "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", + "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", + "service": "Azure Storage", + "severity": "Alto", + "text": "Uso de tokens de Azure Active Directory (Azure AD) para el acceso a blobs", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Al asignar un rol a un usuario, grupo o aplicación, conceda a esa entidad de seguridad solo los permisos necesarios para que pueda realizar sus tareas. Limitar el acceso a los recursos ayuda a evitar el uso indebido no intencionado y malintencionado de los datos.", + "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", + "service": "Azure Storage", + "severity": "Medio", + "text": "Privilegios mínimos en los permisos de IaM", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Una SAS de delegación de usuarios está protegida con credenciales de Azure Active Directory (Azure AD) y también con los permisos especificados para la SAS. Una SAS de delegación de usuarios es análoga a una SAS de servicio en cuanto a su ámbito y función, pero ofrece ventajas de seguridad sobre la SAS de servicio. ", + "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", + "service": "Azure Storage", + "severity": "Alto", + "text": "Al usar SAS, prefiera \"SAS de delegación de usuarios\" en lugar de SAS basada en claves de cuenta de almacenamiento.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Las claves de la cuenta de almacenamiento (\"claves compartidas\") tienen muy pocas funcionalidades de auditoría. Si bien se puede monitorear quién o cuándo obtuvo una copia de las claves, una vez que las claves están en manos de varias personas, es imposible atribuir el uso a un usuario específico. Confiar únicamente en la autenticación de AAD facilita la vinculación del acceso al almacenamiento a un usuario. ", + "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", + "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere la posibilidad de deshabilitar las claves de la cuenta de almacenamiento, de modo que solo se admita el acceso a AAD (y la SAS de delegación de usuarios).", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Use los datos del registro de actividad para identificar \"cuándo\", \"quién\", \"qué\" y \"cómo\" se está viendo o cambiando la seguridad de la cuenta de almacenamiento (es decir, claves de cuenta de almacenamiento, directivas de acceso, etc.).", + "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", + "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere la posibilidad de usar Azure Monitor para auditar las operaciones del plano de control en la cuenta de almacenamiento", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Una directiva de expiración de claves le permite establecer un recordatorio para la rotación de las claves de acceso a la cuenta. El recordatorio se muestra si ha transcurrido el intervalo especificado y las teclas aún no se han girado.", + "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", + "service": "Azure Storage", + "severity": "Medio", + "text": "Al usar claves de cuenta de almacenamiento, considere la posibilidad de habilitar una \"directiva de expiración de claves\"", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Una directiva de expiración de SAS especifica un intervalo recomendado durante el cual la SAS es válida. Las directivas de expiración de SAS se aplican a una SAS de servicio o a una SAS de cuenta. Cuando un usuario genera una SAS de servicio o una SAS de cuenta con un intervalo de validez mayor que el intervalo recomendado, verá una advertencia.", + "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", + "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", + "service": "Azure Storage", + "severity": "Medio", + "text": "Considere la posibilidad de configurar una directiva de expiración de SAS", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Las directivas de acceso almacenadas ofrecen la opción de revocar los permisos de una SAS de servicio sin tener que volver a generar las claves de la cuenta de almacenamiento. ", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", + "service": "Azure Storage", + "severity": "Medio", + "text": "Considere la posibilidad de vincular SAS a una directiva de acceso almacenada", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", + "service": "Azure Storage", + "severity": "Medio", + "text": "Considere la posibilidad de configurar el repositorio de código fuente de la aplicación para detectar cadenas de conexión protegidas y claves de cuenta de almacenamiento.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Lo ideal es que la aplicación use una identidad administrada para autenticarse en Azure Storage. Si esto no es posible, considere la posibilidad de tener la credencial de almacenamiento (cadena de conexión, clave de cuenta de almacenamiento, SAS, credencial de entidad de servicio) en Azure KeyVault o un servicio equivalente.", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere la posibilidad de almacenar cadenas de conexión en Azure KeyVault (en escenarios en los que las identidades administradas no son posibles)", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Use los tiempos de expiración a corto plazo en una SAS de servicio SAS ad hoc o en una SAS de cuenta. De esta manera, incluso si una SAS se ve comprometida, es válida solo por un corto tiempo. Esta práctica es especialmente importante si no puede hacer referencia a una directiva de acceso almacenada. Los tiempos de expiración a corto plazo también limitan la cantidad de datos que se pueden escribir en un blob al limitar el tiempo disponible para cargarlo.", + "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", + "severity": "Alto", + "text": "Esfuércese por obtener períodos de validez cortos para SAS ad-hoc", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Al crear una SAS, sea lo más específico y restrictivo posible. Prefiera una SAS para un solo recurso y operación en lugar de una SAS que proporciona un acceso mucho más amplio.", + "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", + "severity": "Medio", + "text": "Aplicación de un ámbito limitado a una SAS", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Una SAS puede incluir parámetros en los que las direcciones IP de cliente o los intervalos de direcciones están autorizados a solicitar un recurso mediante la SAS. ", + "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", + "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", + "service": "Azure Storage", + "severity": "Medio", + "text": "Considere la posibilidad de definir el ámbito de SAS en una dirección IP de cliente específica, siempre que sea posible", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Una SAS no puede restringir la cantidad de datos que carga un cliente; Dado el modelo de precios de la cantidad de almacenamiento a lo largo del tiempo, podría tener sentido validar si los clientes cargaron contenido de gran tamaño malintencionado.", + "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", + "service": "Azure Storage", + "severity": "Bajo", + "text": "Considere la posibilidad de comprobar los datos cargados, después de que los clientes hayan usado una SAS para cargar un archivo. ", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Al acceder a Blob Storage a través de SFTP mediante una \"cuenta de usuario local\", no se aplican los controles RBAC \"habituales\". El acceso a blobs a través de NFS o REST puede ser más restrictivo que el acceso SFTP. Desafortunadamente, a partir de principios de 2023, los usuarios locales son la única forma de administración de identidades que actualmente se admite para el punto de conexión SFTP", + "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", + "service": "Azure Storage", + "severity": "Alto", + "text": "SFTP: Limite la cantidad de \"usuarios locales\" para el acceso SFTP y audite si el acceso es necesario a lo largo del tiempo.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", + "service": "Azure Storage", + "severity": "Medio", + "text": "SFTP: El punto de conexión SFTP no admite ACL similares a POSIX.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "El almacenamiento es compatible con CORS (Cross-Origin Resource Sharing), es decir, una función HTTP que permite a las aplicaciones web de un dominio diferente relajar la política del mismo origen. Al habilitar CORS, mantenga CorsRules con el mínimo privilegio.", + "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", + "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", + "service": "Azure Storage", + "severity": "Alto", + "text": "Evite las políticas de CORS demasiado amplias", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Los datos en reposo siempre están cifrados en el lado del servidor y, además, también pueden estar cifrados en el lado del cliente. El cifrado del lado del servidor puede realizarse mediante una clave administrada por la plataforma (predeterminada) o una clave administrada por el cliente. El cifrado del lado cliente puede producirse haciendo que el cliente proporcione una clave de cifrado y descifrado por blob a Azure Storage o controlando completamente el cifrado en el lado cliente. por lo tanto, no depende en absoluto de Azure Storage para obtener garantías de confidencialidad.", + "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", + "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", + "service": "Azure Storage", + "severity": "Alto", + "text": "Determine cómo se deben cifrar los datos en reposo. Comprender el modelo de subprocesos para los datos.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", + "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", + "service": "Azure Storage", + "severity": "Medio", + "text": "Determine qué cifrado de plataforma se debe usar o si se debe usar.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", + "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "service": "Azure Storage", + "severity": "Medio", + "text": "Determine qué cifrado del lado del cliente se debe usar o si.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Aproveche el Explorador de Resource Graph (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) para buscar cuentas de almacenamiento que permitan el acceso anónimo a blobs.", + "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", + "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere si se necesita acceso público a blobs o si se puede deshabilitar para determinadas cuentas de almacenamiento. ", + "waf": "Seguridad" + }, { "checklist": "SAP Checklist", "guid": "4620dc87-e948-4ce8-8426-f3e6e5d7bd85", @@ -2532,6 +2900,46 @@ "text": "Haga que la configuración de tolerancia ante desastres del sitio se considere y cambie correctamente para su negocio si es necesario.", "waf": "Fiabilidad" }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "Alto", + "text": "Habilite la redundancia de zona para Azure Cache for Redis. Azure Cache for Redis admite configuraciones con redundancia de zona en los niveles Premium y Enterprise. Una caché con redundancia de zona puede colocar sus nodos en diferentes zonas de disponibilidad de Azure en la misma región. Elimina la interrupción del centro de datos o de la zona de disponibilidad como único punto de error y aumenta la disponibilidad general de la caché.", + "waf": "Fiabilidad" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "Medio", + "text": "Configure la persistencia de datos para una instancia de Azure Cache for Redis. Dado que los datos de caché se almacenan en la memoria, un error poco frecuente y no planeado de varios nodos puede hacer que se eliminen todos los datos. Para evitar la pérdida total de datos, la persistencia de Redis le permite tomar instantáneas periódicas de datos en memoria y almacenarlas en su cuenta de almacenamiento.", + "waf": "Fiabilidad" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "Medio", + "text": "Use la cuenta de almacenamiento con redundancia geográfica para conservar los datos de Azure Cache for Redis o con redundancia zonal donde la redundancia geográfica no esté disponible", + "waf": "Fiabilidad" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "Medio", + "text": "Configure la replicación geográfica pasiva para instancias de Azure Cache for Redis Premium. La replicación geográfica es un mecanismo para vincular dos o más instancias de Azure Cache for Redis, que normalmente abarcan dos regiones de Azure. La replicación geográfica está diseñada principalmente para la recuperación ante desastres entre regiones. Dos instancias de caché de nivel Premium se conectan a través de la replicación geográfica de una manera que proporciona lecturas y escrituras en la caché principal, y esos datos se replican en la caché secundaria.", + "waf": "Fiabilidad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2542,6 +2950,17 @@ "text": "Restringir el uso de usuarios locales en cargas de trabajo de SQL en Synapse", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No se requieren configuraciones adicionales, ya que esto está habilitado en una implementación predeterminada.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Cifrar datos confidenciales en tránsito", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2553,6 +2972,15 @@ "text": "Uso de la identidad administrada para autenticarse en los servicios", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Habilitar el cifrado de datos en reposo de forma predeterminada", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2563,6 +2991,17 @@ "text": "Separe y limite los usuarios administrativos o con muchos privilegios y habilite las directivas condicionales y de MFA", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Uso de almacenes de claves para almacenar la CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Usar la opción de clave administrada por el cliente en el cifrado de datos en reposo cuando sea necesario", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2595,6 +3034,16 @@ "text": "Uso del área de trabajo de red virtual administrada para restringir el acceso a través de la red pública de Internet", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use el identificador de Microsoft Entra como método de autenticación predeterminado.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "severity": "Alto", + "text": "Use el identificador de Microsoft Entra como método de autenticación predeterminado y deshabilite el acceso local siempre que sea posible", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2606,6 +3055,16 @@ "text": "Configurar puntos de conexión privados para conectarse a los servicios externos y deshabilitar el acceso público", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use el identificador de Microsoft Entra como método de autenticación predeterminado.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Uso de la identidad administrada para autenticarse en los servicios", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2616,6 +3075,15 @@ "text": "Si se habilita el acceso público, se recomienda encarecidamente configurar las reglas de firewall de IP", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Configuración de directivas de acceso condicional para restringir el acceso en el plano de datos", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2626,6 +3094,16 @@ "text": "Implemente máquinas virtuales SHIR en la red virtual si trabaja con datos confidenciales que no deben salir de la red corporativa", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Restringir la exposición de claves y seguridades", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "severity": "Alto", + "text": "Use Azure Key Vaults para almacenar secretos y créditos.", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2637,6 +3115,37 @@ "text": "Habilitar la protección de exfiltración de datos (DEP)", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "severity": "Alto", + "text": "Separe y limite los usuarios con muchos privilegios/administrativos", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Al crear un espacio de nombres de Event Hubs, se crea automáticamente una regla de directiva denominada RootManageSharedAccessKey para el espacio de nombres. Esta política tiene permisos de administración para todo el espacio de nombres. Se recomienda tratar esta regla como una cuenta raíz administrativa y no usarla en la aplicación. Puede crear reglas de directiva adicionales en la pestaña Configurar para el espacio de nombres en el portal, a través de PowerShell o la CLI de Azure. Evite el uso de métodos o cuentas de autenticación locales, estos deben deshabilitarse siempre que sea posible. En su lugar, use Azure AD para autenticarse siempre que sea posible.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Autenticar el acceso a los recursos de Event Hubs mediante firmas de acceso compartido (SAS) y restringir a los usuarios locales", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use el control de acceso basado en roles de Azure (RBAC de Azure) para administrar el acceso a los recursos de Azure a través de asignaciones de roles integradas. Los roles de RBAC de Azure se pueden asignar a usuarios, grupos, entidades de servicio e identidades administradas.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Uso de RBAC de Azure para precisar el acceso ", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2648,6 +3157,16 @@ "text": "Cifrado de datos en reposo mediante claves administradas por el cliente para el área de trabajo", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "El servicio admite la deshabilitación del acceso a la red pública mediante el uso de una regla de filtrado de ACL de IP de nivel de servicio (no NSG ni Azure Firewall) o mediante un conmutador de alternancia \"Deshabilitar el acceso a la red pública\".", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Desactivar el acceso a la red pública", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2659,6 +3178,15 @@ "text": "Cifrado de datos en tránsito ", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Uso de redes virtuales para aislar el tráfico a través de una red restringida ", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2669,6 +3197,111 @@ "text": "Almacenamiento de contraseñas, seguridades y claves en Azure Key Vault", "waf": "Seguridad" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "Medio", + "text": "Implemente puntos de conexión privados para todos los recursos de Azure que admitan la característica Private Link para establecer un punto de acceso privado para los recursos.", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Puede almacenar credenciales o valores secretos en una instancia de Azure Key Vault y usarlos durante la ejecución de la canalización para pasarlos a sus actividades.", + "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "Medio", + "text": "Uso de secretos de Azure Key Vault en actividades de canalización", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric controla el acceso a los datos mediante espacios de trabajo. En los espacios de trabajo, los datos aparecen en forma de elementos de tejido y los usuarios no pueden ver ni usar elementos (datos) a menos que les conceda acceso al espacio de trabajo. Puede encontrar más información sobre los permisos del área de trabajo y los elementos en Modelo de permisos.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Utilice las funciones del área de trabajo para proporcionar acceso a los usuarios en los datos", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "RBAC de OneLake usa asignaciones de roles para aplicar permisos a sus miembros.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Utilice RBAC en Onelake para proporcionar acceso detallado a los datos en Tablas/Archivos Onelake ", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Tenga en cuenta el acceso del usuario tanto en la ubicación de destino como en la de origen del acceso directo", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Al usar accesos directos, la identidad del usuario también debe tener acceso en la ubicación de destino del acceso directo", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No todos los usuarios necesitan tener acceso a todo el espacio de trabajo mediante roles, por lo tanto, restrinja la asignación de roles en todo el espacio de trabajo y solo comparta el elemento con el usuario mediante la función de compartir elemento o el permiso de administración en Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Restrinja el suministro de roles de nivel de área de trabajo a los usuarios en lugar de compartir un elemento solo con los usuarios", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Utilice características como RLS, CLS y enmascaramiento dinámico de datos para mejorar los requisitos de seguridad de datos en cargas de trabajo SQL.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Limite el acceso a los datos mediante la definición de RLS, CLS y enmascaramiento de datos dinámicos en los puntos de conexión de análisis de SQL y Warehouse", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use características como RLS y OLS en Power BI para tener más características de seguridad en los modelos semánticos", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Limite el acceso a los datos definiendo RLS y OLS en modelos semánticos en Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "En Fabric, todos los datos que se almacenan en OneLake se cifran en reposo", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Cifrar datos en reposo", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Los datos en tránsito a través de la red pública de Internet entre los servicios de Microsoft siempre se cifran con al menos TLS 1.2. Fabric negocia con TLS 1.3 siempre que sea posible.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Cifrar datos en tránsito", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2679,6 +3312,16 @@ "text": "Restrinja el uso de usuarios locales siempre que sea necesario", "waf": "Seguridad" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No hay necesidad de hacer nada. Cada solicitud para conectarse a Fabric se autentica con Microsoft Entra ID, lo que permite a los usuarios conectarse de forma segura a Fabric desde su oficina corporativa, cuando trabajan en casa o desde una ubicación remota.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Usar el identificador de Microsoft Entra como método de autenticación predeterminado", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2690,6 +3333,16 @@ "text": "Uso de la identidad administrada para autenticarse en los servicios", "waf": "Seguridad" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Una identidad de área de trabajo de Fabric es una entidad de servicio administrada automáticamente que se puede asociar a un área de trabajo de Fabric. Las identidades del área de trabajo se pueden crear en la configuración del área de trabajo de cualquier área de trabajo, excepto Mis áreas de trabajo. A una identidad de área de trabajo se le asigna automáticamente el rol de colaborador del área de trabajo y tiene acceso a los elementos del área de trabajo. Limitación: Se produce un error al escribir en el destino del acceso directo cuando se utiliza la identidad del área de trabajo como método de autenticación. Las conexiones con workspace-identity-authentication solo se pueden usar en accesos directos y canalizaciones de datos de Onelake.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Usar la identidad del área de trabajo para autenticarse en los servicios", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2700,6 +3353,35 @@ "text": "Separe y limite los usuarios administrativos o con muchos privilegios y habilite las directivas condicionales y de MFA", "waf": "Seguridad" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Concesión de permisos de identidad en la cuenta de almacenamiento", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Proporcionar roles RBAC en la cuenta de almacenamiento a la identidad administrada para establecer una conexión correcta", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "service": "Azure Data Factory", + "severity": "Medio", + "text": "Deshabilite el acceso a través de Internet público y configure las reglas de firewall o las reglas de servicios de confianza", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Las áreas de trabajo de Fabric con una identidad de área de trabajo pueden leer o escribir de forma segura en cuentas de Azure Data Lake Storage Gen2 habilitadas para firewall a través del acceso de confianza al área de trabajo para accesos directos de OneLake.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Configurar el acceso al área de trabajo de confianza para acceder a la cuenta de almacenamiento detrás del firewall ", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2709,6 +3391,17 @@ "text": "Implemente máquinas virtuales SHIR en la red virtual si trabaja con datos confidenciales que no deben salir de la red corporativa", "waf": "Seguridad" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Las redes virtuales administradas son redes virtuales creadas y administradas por Microsoft Fabric para cada área de trabajo de Fabric. Las redes virtuales administradas proporcionan aislamiento de red para las cargas de trabajo de Fabric Spark, lo que significa que los clústeres de proceso se implementan en una red dedicada y ya no forman parte de la red virtual compartida. Solo se admite para la carga de trabajo de Spark en Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Use la opción de red virtual administrada si tiene necesidades de aislamiento de red", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2719,6 +3412,17 @@ "text": "Uso de IR de red virtual administrada para restringir el acceso a través de la red pública de Internet para Azure Integration Runtime", "waf": "Seguridad" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Los puntos de conexión privados administrados son una característica que permite el acceso seguro y privado a los orígenes de datos de las cargas de trabajo de Fabric Spark. No se puede usar el grupo de inicio con PE administrado", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Configuración de puntos de conexión privados administrados para acceder a los servicios de Azure", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2727,7 +3431,83 @@ "link": "https://learn.microsoft.com/azure/data-factory/managed-virtual-network-private-endpoint#managed-private-endpoints", "service": "Azure Data Factory", "severity": "Medio", - "text": "Configuración de puntos de conexión privados administrados para conectarse a recursos mediante Azure IR administrado", + "text": "Configuración de puntos de conexión privados administrados para conectarse a recursos mediante Azure IR administrado", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric usa una dirección IP privada de la red virtual. El punto de conexión permite a los usuarios de la red comunicarse con Fabric a través de la dirección IP privada mediante enlaces privados.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Configure Private Links para acceder a los recursos de su propia red virtual de Azure, es decir, al tráfico que entra en su entorno de Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "El momento en que un usuario se autentica, el acceso se determina en función de un conjunto de directivas que pueden incluir la dirección IP, la ubicación y los dispositivos administrados.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Configurar el acceso condicional de ID de Microsoft Entra si un usuario intenta acceder a su entorno de Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "En Azure, una etiqueta de servicio es un grupo definido de direcciones IP que se administra automáticamente, como un grupo, para minimizar la complejidad de las actualizaciones o los cambios en las reglas de seguridad de red.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Puede usar etiquetas de servicio de Azure para habilitar las conexiones hacia y desde Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "opcional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Puedes agregar URL de Fabric a tu lista de permitidos", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "opcional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Puede agregar direcciones URL de Power BI a la lista de permitidos", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Seguridad" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "La puerta de enlace de datos le permite conectar Azure y otros servicios de datos a Microsoft Fabric y Power Platform para comunicarse de forma segura con el origen de datos, ejecutar consultas y transmitir los resultados al servicio.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "Medio", + "text": "Configure y use la puerta de enlace de datos local o la puerta de enlace de datos de red virtual para conectarse a orígenes locales o detrás de una red virtual", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Con Azure Private Link, puede conectarse a varias implementaciones de plataforma como servicio (PaaS) en Azure a través de un punto de conexión privado. Un punto de conexión privado es una dirección IP privada dentro de una red virtual y una subred específicas", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", + "severity": "Medio", + "text": "Configuración de vínculos privados para conectarse a orígenes en la red virtual del cliente y la factoría de datos", "waf": "Seguridad" }, { @@ -2771,6 +3551,28 @@ "text": "Almacenamiento de contraseñas y secretos en Azure Key Vault", "waf": "Seguridad" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Puede almacenar credenciales o valores secretos en una instancia de Azure Key Vault y usarlos durante la ejecución de la canalización para pasarlos a sus actividades.", + "guid": "6f4a1652-bddd-4ea8-a487-cdec4861bc3b", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "Medio", + "text": "Uso de secretos de Azure Key Vault en actividades de canalización", + "waf": "Seguridad" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Puede cifrar y almacenar credenciales para cualquiera de los almacenes de datos locales (servicios vinculados con información confidencial) en un equipo con tiempo de ejecución de integración autohospedado.", + "guid": "c14aeb7e-66e8-4d9a-9bec-218e6436b173", + "link": "https://learn.microsoft.com/azure/data-factory/encrypt-credentials-self-hosted-integration-runtime", + "service": "Azure Data Factory", + "severity": "Medio", + "text": "Cifrado de credenciales para el entorno local mediante almacenes de datos SHIR en Azure Data Factory", + "waf": "Seguridad" + }, { "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "guid": "6db55f57-9603-4334-adf9-cc23418db612", @@ -3035,6 +3837,17 @@ "text": "Limite los derechos de creación de clústeres.", "waf": "Seguridad" }, + { + "arm-service": "Microsoft.Databricks/workspaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Los administradores de cuentas pueden configurar una configuración del área de trabajo denominada RestrictWorkspaceAdmins para restringir a los administradores del área de trabajo para que solo cambien el propietario de un trabajo a sí mismos y la configuración de ejecución del trabajo como a una entidad de servicio en la que tengan el rol de usuario de entidad de servicio.", + "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", + "severity": "Alto", + "text": "Restringir a los administradores del espacio de trabajo", + "waf": "Seguridad" + }, { "arm-service": "Microsoft.Databricks/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5368,1152 +6181,784 @@ "checklist": "Azure Landing Zone Review", "guid": "f541acdc-e979-4377-acdb-3751ab2ab13a", "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", - "service": "VM", - "severity": "Medio", - "text": "Use directivas de invitado de Azure para implementar automáticamente configuraciones de software a través de extensiones de máquina virtual y aplicar una configuración de máquina virtual de línea base compatible.", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Compute/virtualMachines", - "checklist": "Azure Landing Zone Review", - "description": "Use las características de configuración de invitado de Azure Policy para auditar y corregir la configuración de la máquina (por ejemplo, el sistema operativo, la aplicación, el entorno) para asegurarse de que los recursos se alinean con las configuraciones esperadas, y Update Management puede aplicar la administración de revisiones para las máquinas virtuales.", - "guid": "da6e55d7-d8a2-4adb-817d-6326af625ca4", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", - "service": "VM", - "severity": "Medio", - "text": "Supervise el desfase de la configuración de seguridad de la máquina virtual a través de Azure Policy.", - "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Compute/virtualMachines", - "checklist": "Azure Landing Zone Review", - "guid": "2476e49f-541a-4cdc-b979-377bcdb3751a", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", - "service": "VM", - "severity": "Medio", - "text": "Use Azure Site Recovery para escenarios de recuperación ante desastres de Azure a Azure Virtual Machines. Esto le permite replicar cargas de trabajo en todas las regiones.", - "training": "https://learn.microsoft.com/training/modules/protect-infrastructure-with-site-recovery/", - "waf": "Operaciones" - }, - { - "arm-service": "Microsoft.RecoveryServices/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "f625ca44-e569-45f2-823a-ce8cb12308ca", - "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", - "service": "Backup", - "severity": "Medio", - "text": "Use funcionalidades de copia de seguridad nativas de Azure o una solución de copia de seguridad de terceros compatible con Azure.", - "training": "https://learn.microsoft.com/training/modules/design-solution-for-backup-disaster-recovery/", - "waf": "Operaciones" - }, - { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", - "checklist": "Azure Landing Zone Review", - "guid": "89cc5e11-aa4d-4c3b-893d-feb99215266a", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", - "service": "WAF", - "severity": "Alto", - "text": "Agregue configuración de diagnóstico para guardar los registros de WAF de los servicios de entrega de aplicaciones, como Azure Front Door y Azure Application Gateway. Revise periódicamente los registros para comprobar si hay ataques y detecciones de falsos positivos.", - "training": "https://learn.microsoft.com/training/modules/capture-application-logs-app-service/", - "waf": "Operaciones" - }, - { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", - "checklist": "Azure Landing Zone Review", - "guid": "7f408960-c626-44cb-a018-347c8d790cdf", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", - "service": "WAF", - "severity": "Medio", - "text": "Envíe registros de WAF desde los servicios de entrega de aplicaciones, como Azure Front Door y Azure Application Gateway, a Microsoft Sentinel. Detecte ataques e integre la telemetría de WAF en su entorno general de Azure.", - "training": "https://learn.microsoft.com/training/paths/sc-200-connect-logs-to-azure-sentinel/", - "waf": "Operaciones" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "5017f154-e3ab-4369-9829-e7e316183687", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview", - "service": "Key Vault", - "severity": "Alto", - "text": "Use Azure Key Vault para almacenar sus secretos y credenciales.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "graph": "ResourceContainers | where type=='microsoft.resources/subscriptions'| parse id with '/subscriptions/' SubscriptionID| project subscriptionId, SubscriptionName = name| join kind=leftouter (Resources| where type == 'microsoft.keyvault/vaults'| project id, name, subscriptionId) on subscriptionId| join kind= leftouter (Resources| where type == 'microsoft.keyvault/vaults'| summarize ResourceCount = count() by subscriptionId) on subscriptionId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 1)", - "guid": "a0477a20-9945-4bda-9333-4f2491163418", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", - "service": "Key Vault", - "severity": "Medio", - "text": "Use diferentes instancias de Azure Key Vaults para diferentes aplicaciones y regiones para evitar límites de escala de transacciones y restringir el acceso a los secretos.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "2ba52752-6944-4008-ae7d-7e4843276d8b", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Aprovisione Azure Key Vault con las directivas de eliminación temporal y purga habilitadas para permitir la protección de retención para los objetos eliminados.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "dc055bcf-619e-48a1-9f98-879525d62688", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Siga un modelo de privilegios mínimos limitando la autorización para eliminar claves, secretos y certificados de forma permanente a roles de identificador personalizados especializados de Microsoft Entra.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "6d70ba6c-97be-4995-8904-83845c986cb2", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Automatice el proceso de gestión y renovación de certificados con autoridades de certificación públicas para facilitar la administración.", - "training": "https://learn.microsoft.com/en-us/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "913156a1-2476-4e49-b541-acdce979377b", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Establezca un proceso automatizado para la rotación de claves y certificados.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "cdb3751a-b2ab-413a-ba6e-55d7d8a2adb1", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Habilite el firewall y el punto de conexión de servicio de red virtual o el punto de conexión privado en el almacén para controlar el acceso al almacén de claves.", - "training": "https://learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "17d6326a-f625-4ca4-9e56-95f2223ace8c", - "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", - "service": "Key Vault", - "severity": "Medio", - "text": "Use el área de trabajo de Log Analytics de Azure Monitor central de la plataforma para auditar el uso de claves, certificados y secretos en cada instancia de Key Vault.", - "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "b12308ca-5017-4f15-9e3a-b3693829e7e3", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Delegue la creación de instancias de Key Vault y el acceso con privilegios, y use Azure Policy para aplicar una configuración coherente y conforme.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-key-vault-networking-settings/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "91163418-2ba5-4275-8694-4008be7d7e48", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Use una instancia de Azure Key Vault por aplicación, por entorno, por región.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "25d62688-6d70-4ba6-a97b-e99519048384", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Medio", - "text": "Si desea traer sus propias claves, es posible que esto no sea compatible con todos los servicios considerados. Implemente la mitigación pertinente para que las inconsistencias no obstaculicen los resultados deseados. Elija los pares de regiones y las regiones de recuperación ante desastres adecuados que minimicen la latencia.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "4ac6b67c-b3a4-4ff9-8e87-b07a7ce7bbdb", - "link": "https://learn.microsoft.com/industry/sovereignty/key-management", - "service": "Key Vault", - "severity": "Medio", - "text": "En el caso de la zona de aterrizaje soberana, use el HSM administrado de Azure Key Vault para almacenar los secretos y las credenciales.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Seguridad" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "4e5695f2-223a-4ce8-ab12-308ca5017f15", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", - "service": "Entra", - "severity": "Medio", - "text": "Use las capacidades de generación de informes de Microsoft Entra ID para generar informes de auditoría de control de acceso.", - "training": "https://learn.microsoft.com/training/modules/monitor-report-aad-security-events/", - "waf": "Seguridad" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "09945bda-4333-44f2-9911-634182ba5275", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", - "service": "Defender", - "severity": "Alto", - "text": "Habilite la administración de la posición de seguridad en la nube de Defender para todas las suscripciones.", - "training": "https://learn.microsoft.com/training/modules/microsoft-defender-cloud-security-posture/", - "waf": "Seguridad" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "36a72a48-fffe-4c40-9747-0ab5064355ba", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", - "service": "Defender", - "severity": "Alto", - "text": "Habilite un plan de protección de carga de trabajo en la nube de Defender para servidores en todas las suscripciones.", - "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", - "waf": "Seguridad" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "77425f48-ecba-43a0-aeac-a3ac733ccc6a", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/connect-azure-subscription", - "service": "Defender", - "severity": "Alto", - "text": "Habilite los planes de protección de cargas de trabajo en la nube de Defender para recursos de Azure en todas las suscripciones.", - "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", + "service": "VM", + "severity": "Medio", + "text": "Use directivas de invitado de Azure para implementar automáticamente configuraciones de software a través de extensiones de máquina virtual y aplicar una configuración de máquina virtual de línea base compatible.", "waf": "Seguridad" }, { "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "24d96b30-61ee-4436-a1cc-d6ef08bc574b", - "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", + "description": "Use las características de configuración de invitado de Azure Policy para auditar y corregir la configuración de la máquina (por ejemplo, el sistema operativo, la aplicación, el entorno) para asegurarse de que los recursos se alinean con las configuraciones esperadas, y Update Management puede aplicar la administración de revisiones para las máquinas virtuales.", + "guid": "da6e55d7-d8a2-4adb-817d-6326af625ca4", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", "service": "VM", - "severity": "Alto", - "text": "Habilite la protección de puntos de conexión en servidores IaaS.", - "training": "https://learn.microsoft.com/training/modules/design-solutions-securing-server-client-endpoints/", + "severity": "Medio", + "text": "Supervise el desfase de la configuración de seguridad de la máquina virtual a través de Azure Policy.", + "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/", "waf": "Seguridad" }, { "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", - "link": "https://learn.microsoft.com/azure/security-center/", + "guid": "2476e49f-541a-4cdc-b979-377bcdb3751a", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", "service": "VM", "severity": "Medio", - "text": "Supervise el desfase de revisiones del sistema operativo base a través de los registros de Azure Monitor y Defender for Cloud.", - "training": "https://learn.microsoft.com/training/modules/create-log-analytics-workspace-microsoft-defender-cloud/", - "waf": "Seguridad" + "text": "Use Azure Site Recovery para escenarios de recuperación ante desastres de Azure a Azure Virtual Machines. Esto le permite replicar cargas de trabajo en todas las regiones.", + "training": "https://learn.microsoft.com/training/modules/protect-infrastructure-with-site-recovery/", + "waf": "Operaciones" }, { - "arm-service": "Microsoft.Insights/components", + "arm-service": "Microsoft.RecoveryServices/vaults", "checklist": "Azure Landing Zone Review", - "guid": "e5f8d79f-2e87-4768-924c-516775c6ea95", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "service": "Monitor", + "guid": "f625ca44-e569-45f2-823a-ce8cb12308ca", + "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", + "service": "Backup", "severity": "Medio", - "text": "Conecte las configuraciones de recursos predeterminadas a un área de trabajo centralizada de Azure Monitor Log Analytics.", - "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", - "waf": "Seguridad" + "text": "Use funcionalidades de copia de seguridad nativas de Azure o una solución de copia de seguridad de terceros compatible con Azure.", + "training": "https://learn.microsoft.com/training/modules/design-solution-for-backup-disaster-recovery/", + "waf": "Operaciones" }, { + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.operationalinsights/workspaces'| extend wsid = properties.customerId| project workspaceResourceId = tolower(id), name, wsid| join (resources| where type == 'microsoft.operationsmanagement/solutions'| where name has 'SecurityInsights'| extend workspaceResourceId = tostring(tolower(properties.workspaceResourceId))| project workspaceResourceId | summarize ResourceCount = count() by workspaceResourceId) on workspaceResourceId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 0)", - "guid": "a56888b2-7e83-4404-bd31-b886528502d1", - "link": "https://learn.microsoft.com/en-us/azure/well-architected/security/monitor-threats#centralized-threat-detection-with-correlated-logs", - "service": "Entra", + "guid": "89cc5e11-aa4d-4c3b-893d-feb99215266a", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", + "service": "WAF", "severity": "Alto", - "text": "Detección centralizada de amenazas con registros correlacionados: consolide los datos de seguridad en una ubicación central donde se puedan correlacionar entre varios servicios a través de SIEM (información de seguridad y gestión de eventos)", - "waf": "Seguridad" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "1761e147-f65e-4d09-bbc2-f464f23e2eba", - "link": "https://learn.microsoft.com/industry/sovereignty/transparency-logs", - "service": "Entra", - "severity": "Medio", - "text": "Para Sovereign Landing Zone, habilite los registros de transparencia en el inquilino de Entra ID.", - "waf": "Seguridad" + "text": "Agregue configuración de diagnóstico para guardar los registros de WAF de los servicios de entrega de aplicaciones, como Azure Front Door y Azure Application Gateway. Revise periódicamente los registros para comprobar si hay ataques y detecciones de falsos positivos.", + "training": "https://learn.microsoft.com/training/modules/capture-application-logs-app-service/", + "waf": "Operaciones" }, { + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "d21a922d-5ca7-427a-82a6-35f7b21f1bfc", - "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", - "service": "Entra", + "guid": "7f408960-c626-44cb-a018-347c8d790cdf", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", + "service": "WAF", "severity": "Medio", - "text": "Para Sovereign Landing Zone, habilite la caja de seguridad del cliente en el inquilino de Entra ID.", - "waf": "Seguridad" + "text": "Envíe registros de WAF desde los servicios de entrega de aplicaciones, como Azure Front Door y Azure Application Gateway, a Microsoft Sentinel. Detecte ataques e integre la telemetría de WAF en su entorno general de Azure.", + "training": "https://learn.microsoft.com/training/paths/sc-200-connect-logs-to-azure-sentinel/", + "waf": "Operaciones" }, { - "arm-service": "Microsoft.Storage/storageAccounts", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "b03ed428-4617-4067-a787-85468b9ccf3f", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Storage", + "guid": "5017f154-e3ab-4369-9829-e7e316183687", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview", + "service": "Key Vault", "severity": "Alto", - "text": "Habilite la transferencia segura a las cuentas de almacenamiento.", - "training": "https://learn.microsoft.com/training/modules/secure-azure-storage-account/", + "text": "Use Azure Key Vault para almacenar sus secretos y credenciales.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "159aac9f-863f-4f48-82cf-00c28fa97a0e", - "link": "https://learn.microsoft.com/azure/storage/blobs/data-protection-overview#recommendations-for-basic-data-protection", - "service": "Storage", - "severity": "Alto", - "text": "Habilite la eliminación temporal de contenedor para que la cuenta de almacenamiento recupere un contenedor eliminado y su contenido.", + "graph": "ResourceContainers | where type=='microsoft.resources/subscriptions'| parse id with '/subscriptions/' SubscriptionID| project subscriptionId, SubscriptionName = name| join kind=leftouter (Resources| where type == 'microsoft.keyvault/vaults'| project id, name, subscriptionId) on subscriptionId| join kind= leftouter (Resources| where type == 'microsoft.keyvault/vaults'| summarize ResourceCount = count() by subscriptionId) on subscriptionId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 1)", + "guid": "a0477a20-9945-4bda-9333-4f2491163418", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", + "service": "Key Vault", + "severity": "Medio", + "text": "Use diferentes instancias de Azure Key Vaults para diferentes aplicaciones y regiones para evitar límites de escala de transacciones y restringir el acceso a los secretos.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", "waf": "Seguridad" }, { "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "108d5099-a11d-4445-bd8b-e12a5e95412e", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", + "guid": "2ba52752-6944-4008-ae7d-7e4843276d8b", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Key Vault", - "severity": "Alto", - "text": "Use los secretos de Key Vault para evitar codificar de forma rígida información confidencial, como credenciales (máquinas virtuales, contraseñas de usuario), certificados o claves.", - "training": "https://learn.microsoft.com/en-us/training/modules/implement-azure-key-vault/", - "waf": "Operaciones" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "d7941d4a-7b6f-458f-8714-2f8f8c059ad4", - "link": "https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies", - "service": "APIM", "severity": "Medio", - "text": "Implementar una política de control de errores a nivel global", - "waf": "Operaciones" + "text": "Aprovisione Azure Key Vault con las directivas de eliminación temporal y purga habilitadas para permitir la protección de retención para los objetos eliminados.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "0b0c0765-ff37-4369-90bd-3eb23ce71b08", - "link": "https://learn.microsoft.com/azure/api-management/set-edit-policies?tabs=form#use-base-element-to-set-policy-evaluation-order", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "dc055bcf-619e-48a1-9f98-879525d62688", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Asegúrese de que todas las políticas de API incluyan un elemento.", - "waf": "Operaciones" + "text": "Siga un modelo de privilegios mínimos limitando la autorización para eliminar claves, secretos y certificados de forma permanente a roles de identificador personalizados especializados de Microsoft Entra.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", - "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "6d70ba6c-97be-4995-8904-83845c986cb2", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Uso de fragmentos de políticas para evitar repetir las mismas definiciones de políticas en varias API", - "waf": "Operaciones" + "text": "Automatice el proceso de gestión y renovación de certificados con autoridades de certificación públicas para facilitar la administración.", + "training": "https://learn.microsoft.com/en-us/training/modules/configure-and-manage-azure-key-vault/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", - "link": "https://learn.microsoft.com/azure/api-management/monetization-support", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "913156a1-2476-4e49-b541-acdce979377b", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Si planeas monetizar tus API, revisa el artículo \"Soporte de monetización\" para conocer las prácticas recomendadas", - "waf": "Operaciones" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "a7d0840a-c8c4-4e83-adec-5ca578eb4049", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor#resource-logs", - "service": "APIM", - "severity": "Alto", - "text": "Habilitación de la configuración de diagnóstico para exportar registros a Azure Monitor", - "waf": "Operaciones" + "text": "Establezca un proceso automatizado para la rotación de claves y certificados.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "8691fa38-45ed-4299-a247-fecd98d35deb", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-app-insights", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "cdb3751a-b2ab-413a-ba6e-55d7d8a2adb1", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Habilitación de Application Insights para obtener telemetría más detallada", - "waf": "Operaciones" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "55fd27bb-76ac-4a91-bc37-049e885be6b7", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor", - "service": "APIM", - "severity": "Alto", - "text": "Configurar alertas sobre las métricas más críticas", - "waf": "Operaciones" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "39460bdb-156f-4dc2-a87f-1e8c11ab0998", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#certificate-management-in-azure-key-vault", - "service": "APIM", - "severity": "Alto", - "text": "Asegúrese de que los certificados SSL personalizados se almacenan en Azure Key Vault para que se pueda acceder a ellos y actualizarlos de forma segura", + "text": "Habilite el firewall y el punto de conexión de servicio de red virtual o el punto de conexión privado en el almacén para controlar el acceso al almacén de claves.", + "training": "https://learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/", "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "e9217997-5f6c-479d-8576-8f2adf706ec8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-ad-authentication-required-for-data-plane-access", - "service": "APIM", - "severity": "Alto", - "text": "Protección de las solicitudes entrantes a las API (plano de datos) con Azure AD", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "17d6326a-f625-4ca4-9e56-95f2223ace8c", + "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", + "service": "Key Vault", + "severity": "Medio", + "text": "Use el área de trabajo de Log Analytics de Azure Monitor central de la plataforma para auditar el uso de claves, certificados y secretos en cada instancia de Key Vault.", + "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "5e5f64ba-c90e-480e-8888-398d96cf0bfb", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-aad", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "b12308ca-5017-4f15-9e3a-b3693829e7e3", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Usar el identificador de Microsoft Entra para autenticar a los usuarios en el Portal para desarrolladores", + "text": "Delegue la creación de instancias de Key Vault y el acceso con privilegios, y use Azure Policy para aplicar una configuración coherente y conforme.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-key-vault-networking-settings/", "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "f8e574ce-280f-49c8-b2ef-68279b081cf3", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-create-groups", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "91163418-2ba5-4275-8694-4008be7d7e48", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Crear grupos adecuados para controlar la visibilidad de los productos", + "text": "Use una instancia de Azure Key Vault por aplicación, por entorno, por región.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "06862505-2d9a-4874-9491-2837b00a3475", - "link": "https://learn.microsoft.com/azure/api-management/backends", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "25d62688-6d70-4ba6-a97b-e99519048384", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Medio", - "text": "Utilice la función Backends para eliminar las configuraciones redundantes de back-end de la API", - "waf": "Operaciones" + "text": "Si desea traer sus propias claves, es posible que esto no sea compatible con todos los servicios considerados. Implemente la mitigación pertinente para que las inconsistencias no obstaculicen los resultados deseados. Elija los pares de regiones y las regiones de recuperación ante desastres adecuados que minimicen la latencia.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "03b125d5-b69b-4739-b7fd-84b86da4933e", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-properties?tabs=azure-portal", - "service": "APIM", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "4ac6b67c-b3a4-4ff9-8e87-b07a7ce7bbdb", + "link": "https://learn.microsoft.com/industry/sovereignty/key-management", + "service": "Key Vault", "severity": "Medio", - "text": "Usar valores con nombre para almacenar valores comunes que se pueden usar en directivas", - "waf": "Operaciones" + "text": "En el caso de la zona de aterrizaje soberana, use el HSM administrado de Azure Key Vault para almacenar los secretos y las credenciales.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "beae759e-4ddb-4326-bf26-47f87d3454b6", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", - "service": "APIM", + "checklist": "Azure Landing Zone Review", + "guid": "4e5695f2-223a-4ce8-ab12-308ca5017f15", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", + "service": "Entra", "severity": "Medio", - "text": "En el caso de la recuperación ante desastres, aproveche el nivel premium con implementaciones escaladas en dos o más regiones para un acuerdo de nivel de servicio del 99,99 %", - "waf": "Fiabilidad" + "text": "Use las capacidades de generación de informes de Microsoft Entra ID para generar informes de auditoría de control de acceso.", + "training": "https://learn.microsoft.com/training/modules/monitor-report-aad-security-events/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", - "link": "https://learn.microsoft.com/azure/api-management/high-availability", - "service": "APIM", - "severity": "Medio", - "text": "Implemente al menos una unidad en dos o más zonas de disponibilidad para obtener un SLA aumentado del 99,99 %", - "waf": "Fiabilidad" + "checklist": "Azure Landing Zone Review", + "guid": "09945bda-4333-44f2-9911-634182ba5275", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", + "service": "Defender", + "severity": "Alto", + "text": "Habilite la administración de la posición de seguridad en la nube de Defender para todas las suscripciones.", + "training": "https://learn.microsoft.com/training/modules/microsoft-defender-cloud-security-posture/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "8d2db6e8-85c6-4118-a52c-ae76a4f27934", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#service-native-backup-capability", - "service": "APIM", + "checklist": "Azure Landing Zone Review", + "guid": "36a72a48-fffe-4c40-9747-0ab5064355ba", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", + "service": "Defender", "severity": "Alto", - "text": "Asegúrese de que haya una rutina de copia de seguridad automatizada", - "waf": "Fiabilidad" + "text": "Habilite un plan de protección de carga de trabajo en la nube de Defender para servidores en todas las suscripciones.", + "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "43e60b94-7bca-43a2-aadf-efb04d63a485", - "link": "https://learn.microsoft.com/azure/api-management/retry-policy", - "service": "APIM", - "severity": "Medio", - "text": "Use directivas para agregar una dirección URL de back-end de conmutación por error y el almacenamiento en caché para reducir las llamadas con errores.", - "waf": "Fiabilidad" + "checklist": "Azure Landing Zone Review", + "guid": "77425f48-ecba-43a0-aeac-a3ac733ccc6a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/connect-azure-subscription", + "service": "Defender", + "severity": "Alto", + "text": "Habilite los planes de protección de cargas de trabajo en la nube de Defender para recursos de Azure en todas las suscripciones.", + "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "8210699f-8d43-45c2-8f19-57e54134bd8f", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-log-event-hubs", - "service": "APIM", - "severity": "Bajo", - "text": "Si necesita iniciar sesión en niveles de alto rendimiento, tenga en cuenta la directiva de Event Hubs", - "waf": "Operaciones" + "arm-service": "Microsoft.Compute/virtualMachines", + "checklist": "Azure Landing Zone Review", + "guid": "24d96b30-61ee-4436-a1cc-d6ef08bc574b", + "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", + "service": "VM", + "severity": "Alto", + "text": "Habilite la protección de puntos de conexión en servidores IaaS.", + "training": "https://learn.microsoft.com/training/modules/design-solutions-securing-server-client-endpoints/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "121bfc39-fa7b-4096-b93b-ab56c1bc0bed", - "link": "https://learn.microsoft.com/azure/api-management/api-management-sample-flexible-throttling", - "service": "APIM", + "arm-service": "Microsoft.Compute/virtualMachines", + "checklist": "Azure Landing Zone Review", + "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", + "link": "https://learn.microsoft.com/azure/security-center/", + "service": "VM", "severity": "Medio", - "text": "Aplicación de directivas de limitación para controlar el número de solicitudes por segundo", - "training": "https://learn.microsoft.com/training/modules/protect-apis-on-api-management/", - "waf": "Rendimiento" + "text": "Supervise el desfase de revisiones del sistema operativo base a través de los registros de Azure Monitor y Defender for Cloud.", + "training": "https://learn.microsoft.com/training/modules/create-log-analytics-workspace-microsoft-defender-cloud/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "bb5f356b-3daf-47a2-a9ee-867a8100bbd5", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-autoscale", - "service": "APIM", + "arm-service": "Microsoft.Insights/components", + "checklist": "Azure Landing Zone Review", + "guid": "e5f8d79f-2e87-4768-924c-516775c6ea95", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "service": "Monitor", "severity": "Medio", - "text": "Configurar el escalado automático para escalar horizontalmente el número de instancias cuando aumenta la carga", - "waf": "Rendimiento" + "text": "Conecte las configuraciones de recursos predeterminadas a un área de trabajo centralizada de Azure Monitor Log Analytics.", + "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "84b94abb-59b6-4b9d-8587-3413669468e8", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-provision-self-hosted-gateway", - "service": "APIM", - "severity": "Medio", - "text": "Implemente puertas de enlace autohospedadas en las que Azure no tenga una región cercana a las API de back-end.", - "waf": "Rendimiento" + "checklist": "Azure Landing Zone Review", + "graph": "resources| where type == 'microsoft.operationalinsights/workspaces'| extend wsid = properties.customerId| project workspaceResourceId = tolower(id), name, wsid| join (resources| where type == 'microsoft.operationsmanagement/solutions'| where name has 'SecurityInsights'| extend workspaceResourceId = tostring(tolower(properties.workspaceResourceId))| project workspaceResourceId | summarize ResourceCount = count() by workspaceResourceId) on workspaceResourceId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 0)", + "guid": "a56888b2-7e83-4404-bd31-b886528502d1", + "link": "https://learn.microsoft.com/en-us/azure/well-architected/security/monitor-threats#centralized-threat-detection-with-correlated-logs", + "service": "Entra", + "severity": "Alto", + "text": "Detección centralizada de amenazas con registros correlacionados: consolide los datos de seguridad en una ubicación central donde se puedan correlacionar entre varios servicios a través de SIEM (información de seguridad y gestión de eventos)", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "1fe8db45-a017-4888-8c4d-4422583cfae0", - "link": "https://learn.microsoft.com/azure/api-management/upgrade-and-scale#upgrade-and-scale", - "service": "APIM", + "checklist": "Azure Landing Zone Review", + "guid": "1761e147-f65e-4d09-bbc2-f464f23e2eba", + "link": "https://learn.microsoft.com/industry/sovereignty/transparency-logs", + "service": "Entra", "severity": "Medio", - "text": "Use el nivel premium para las cargas de trabajo de producción.", - "waf": "Fiabilidad" + "text": "Para Sovereign Landing Zone, habilite los registros de transparencia en el inquilino de Entra ID.", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "1b8d68a4-66cd-44d5-ba94-3ee94440e8d6", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region#-route-api-calls-to-regional-backend-services", - "service": "APIM", + "checklist": "Azure Landing Zone Review", + "guid": "d21a922d-5ca7-427a-82a6-35f7b21f1bfc", + "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "service": "Entra", "severity": "Medio", - "text": "En el modelo de varias regiones, use directivas para enrutar las solicitudes a los back-ends regionales en función de la disponibilidad o la latencia.", - "waf": "Fiabilidad" + "text": "Para Sovereign Landing Zone, habilite la caja de seguridad del cliente en el inquilino de Entra ID.", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "46f07d33-ef9a-44e8-8f98-67c097c5d8cd", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#api-management-limits", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Landing Zone Review", + "guid": "b03ed428-4617-4067-a787-85468b9ccf3f", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Storage", "severity": "Alto", - "text": "Tenga en cuenta los límites de APIM", - "waf": "Fiabilidad" + "text": "Habilite la transferencia segura a las cuentas de almacenamiento.", + "training": "https://learn.microsoft.com/training/modules/secure-azure-storage-account/", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "10f58602-f0f9-4d77-972a-956f6e0f2600", - "link": "https://learn.microsoft.com/en-us/azure/api-management/self-hosted-gateway-overview", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Landing Zone Review", + "guid": "159aac9f-863f-4f48-82cf-00c28fa97a0e", + "link": "https://learn.microsoft.com/azure/storage/blobs/data-protection-overview#recommendations-for-basic-data-protection", + "service": "Storage", "severity": "Alto", - "text": "Asegúrese de que las implementaciones de puerta de enlace autohospedadas sean resistentes.", - "waf": "Fiabilidad" + "text": "Habilite la eliminación temporal de contenedor para que la cuenta de almacenamiento recupere un contenedor eliminado y su contenido.", + "waf": "Seguridad" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "7519e385-a88b-4d34-966b-6269d686e890", - "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", - "service": "APIM", - "severity": "Medio", - "text": "Uso de Azure Front Door delante de APIM para la implementación en varias regiones", - "waf": "Rendimiento" + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Landing Zone Review", + "guid": "108d5099-a11d-4445-bd8b-e12a5e95412e", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", + "service": "Key Vault", + "severity": "Alto", + "text": "Use los secretos de Key Vault para evitar codificar de forma rígida información confidencial, como credenciales (máquinas virtuales, contraseñas de usuario), certificados o claves.", + "training": "https://learn.microsoft.com/en-us/training/modules/implement-azure-key-vault/", + "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "cd45c90e-7690-4753-930b-bf290c69c074", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#virtual-network-integration", + "guid": "d7941d4a-7b6f-458f-8714-2f8f8c059ad4", + "link": "https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies", "service": "APIM", "severity": "Medio", - "text": "Implementación del servicio dentro de una red virtual (VNet)", - "waf": "Seguridad" + "text": "Implementar una política de control de errores a nivel global", + "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "02661582-b3d1-48d1-9d7b-c6a918a0ca33", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", + "guid": "0b0c0765-ff37-4369-90bd-3eb23ce71b08", + "link": "https://learn.microsoft.com/azure/api-management/set-edit-policies?tabs=form#use-base-element-to-set-policy-evaluation-order", "service": "APIM", "severity": "Medio", - "text": "Implemente grupos de seguridad de red (NSG) en las subredes para restringir o supervisar el tráfico hacia/desde APIM.", - "waf": "Seguridad" + "text": "Asegúrese de que todas las políticas de API incluyan un elemento.", + "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "67437a28-2721-4a2c-becd-caa54c8237a5", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", + "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", + "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", "service": "APIM", "severity": "Medio", - "text": "Implemente puntos de conexión privados para filtrar el tráfico entrante cuando APIM no se implemente en una red virtual.", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "d698adbd-3288-44cb-b10a-9b572da395ae", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#disable-public-network-access", - "service": "APIM", - "severity": "Alto", - "text": "Deshabilitar el acceso a la red pública", - "waf": "Seguridad" + "text": "Uso de fragmentos de políticas para evitar repetir las mismas definiciones de políticas en varias API", + "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "0674d750-0c6f-4ac0-8717-ceec04d0bdbd", - "link": "https://learn.microsoft.com/azure/api-management/automation-manage-api-management", + "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", + "link": "https://learn.microsoft.com/azure/api-management/monetization-support", "service": "APIM", "severity": "Medio", - "text": "Simplifique la administración con scripts de automatización de PowerShell", + "text": "Si planeas monetizar tus API, revisa el artículo \"Soporte de monetización\" para conocer las prácticas recomendadas", "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "c385bfcd-49fd-4786-81ba-cedbb4c57345", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/app-platform/api-management/platform-automation-and-devops#design-recommendations", + "guid": "a7d0840a-c8c4-4e83-adec-5ca578eb4049", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor#resource-logs", "service": "APIM", - "severity": "Medio", - "text": "Configure APIM a través de la infraestructura como código. Revise las prácticas recomendadas de DevOps desde el acelerador de zonas de aterrizaje de API de Cloud Adaption Framework", + "severity": "Alto", + "text": "Habilitación de la configuración de diagnóstico para exportar registros a Azure Monitor", "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "6c3a27c0-197f-426c-9ffa-86fed51d9ab6", - "link": "https://learn.microsoft.com/azure/api-management/visual-studio-code-tutorial", + "guid": "8691fa38-45ed-4299-a247-fecd98d35deb", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-app-insights", "service": "APIM", "severity": "Medio", - "text": "Promover el uso de la extensión APIM de Visual Studio Code para un desarrollo de API más rápido", + "text": "Habilitación de Application Insights para obtener telemetría más detallada", "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "354f1c03-8112-4965-85ad-c0074bddf231", - "link": "https://learn.microsoft.com/azure/api-management/devops-api-development-templates", + "guid": "55fd27bb-76ac-4a91-bc37-049e885be6b7", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor", "service": "APIM", - "severity": "Medio", - "text": "Implemente DevOps y CI/CD en su flujo de trabajo", + "severity": "Alto", + "text": "Configurar alertas sobre las métricas más críticas", "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "b6439493-426a-45f3-9697-cf65baee208d", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates-for-clients", + "guid": "39460bdb-156f-4dc2-a87f-1e8c11ab0998", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#certificate-management-in-azure-key-vault", "service": "APIM", - "severity": "Medio", - "text": "API seguras mediante la autenticación de certificados de cliente", + "severity": "Alto", + "text": "Asegúrese de que los certificados SSL personalizados se almacenan en Azure Key Vault para que se pueda acceder a ellos y actualizarlos de forma segura", "waf": "Seguridad" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "2a67d143-1033-4c0a-8732-680896478f08", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates", + "guid": "e9217997-5f6c-479d-8576-8f2adf706ec8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-ad-authentication-required-for-data-plane-access", "service": "APIM", - "severity": "Medio", - "text": "Servicios de back-end seguros mediante la autenticación de certificados de cliente", + "severity": "Alto", + "text": "Protección de las solicitudes entrantes a las API (plano de datos) con Azure AD", "waf": "Seguridad" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "074435f5-4a46-41ac-b521-d6114cb5d845", - "link": "https://learn.microsoft.com/azure/api-management/mitigate-owasp-api-threats", + "guid": "5e5f64ba-c90e-480e-8888-398d96cf0bfb", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-aad", "service": "APIM", "severity": "Medio", - "text": "Revise el artículo \"Recomendaciones para mitigar las 10 principales amenazas de seguridad de la API de OWASP\" y compruebe qué se aplica a sus API", + "text": "Usar el identificador de Microsoft Entra para autenticar a los usuarios en el Portal para desarrolladores", "waf": "Seguridad" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", - "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", + "guid": "f8e574ce-280f-49c8-b2ef-68279b081cf3", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-create-groups", "service": "APIM", "severity": "Medio", - "text": "Utilice la función Autorizaciones para simplificar la administración del token de OAuth 2.0 para las API de back-end", + "text": "Crear grupos adecuados para controlar la visibilidad de los productos", "waf": "Seguridad" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "2deee033-b906-4bc2-9f26-c8d3699fe091", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-manage-protocols-ciphers", + "guid": "06862505-2d9a-4874-9491-2837b00a3475", + "link": "https://learn.microsoft.com/azure/api-management/backends", "service": "APIM", - "severity": "Alto", - "text": "Utilice la versión más reciente de TLS al cifrar la información en tránsito. Deshabilite los protocolos y cifrados obsoletos e innecesarios cuando sea posible.", - "waf": "Seguridad" + "severity": "Medio", + "text": "Utilice la función Backends para eliminar las configuraciones redundantes de back-end de la API", + "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "f8af3d94-1d2b-4070-846f-849197524258", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#im-8-restrict-the-exposure-of-credential-and-secrets", + "guid": "03b125d5-b69b-4739-b7fd-84b86da4933e", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-properties?tabs=azure-portal", "service": "APIM", - "severity": "Alto", - "text": "Asegúrese de que los secretos (valores con nombre) se almacenan en Azure Key Vault para que se pueda acceder a ellos y actualizarlos de forma segura", - "waf": "Seguridad" + "severity": "Medio", + "text": "Usar valores con nombre para almacenar valores comunes que se pueden usar en directivas", + "waf": "Operaciones" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "791abd8b-7706-4e31-9569-afefde724be3", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#managed-identities", + "guid": "beae759e-4ddb-4326-bf26-47f87d3454b6", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", "service": "APIM", "severity": "Medio", - "text": "Uso de identidades administradas para autenticarse en otros recursos de Azure siempre que sea posible", - "waf": "Seguridad" + "text": "En el caso de la recuperación ante desastres, aproveche el nivel premium con implementaciones escaladas en dos o más regiones para un acuerdo de nivel de servicio del 99,99 %", + "waf": "Fiabilidad" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "220c4ca6-6688-476b-b2b5-425a78e6fb87", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", + "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", + "link": "https://learn.microsoft.com/azure/api-management/high-availability", "service": "APIM", - "severity": "Alto", - "text": "Uso del firewall de aplicaciones web (WAF) mediante la implementación de Application Gateway delante de APIM", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.DBforMySQL/servers", - "checklist": "MySQL Review Checklist", - "guid": "388c3e25-e800-4ad2-9df3-f3d6ae1050b7", - "link": "https://learn.microsoft.com/azure/mysql/flexible-server/overview", - "service": "Azure MySQL", "severity": "Medio", - "text": "Aproveche el servidor flexible", + "text": "Implemente al menos una unidad en dos o más zonas de disponibilidad para obtener un SLA aumentado del 99,99 %", "waf": "Fiabilidad" }, { - "arm-service": "Microsoft.DBforMySQL/servers", - "checklist": "MySQL Review Checklist", - "guid": "de3aad1e-8c38-4ec9-9666-7313c005674b", - "link": "https://learn.microsoft.com/azure/mysql/flexible-server/overview#high-availability-within-and-across-availability-zones", - "service": "Azure MySQL", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "8d2db6e8-85c6-4118-a52c-ae76a4f27934", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#service-native-backup-capability", + "service": "APIM", "severity": "Alto", - "text": "Aproveche las zonas de disponibilidad cuando corresponda regionalmente", + "text": "Asegúrese de que haya una rutina de copia de seguridad automatizada", "waf": "Fiabilidad" }, { - "arm-service": "Microsoft.DBforMySQL/servers", - "checklist": "MySQL Review Checklist", - "guid": "1e944a45-9c37-43e7-bd61-623b365a917e", - "link": "https://learn.microsoft.com/azure/mysql/flexible-server/overview#setup-hybrid-or-multi-cloud-data-synchronization-with-data-in-replication", - "service": "Azure MySQL", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "43e60b94-7bca-43a2-aadf-efb04d63a485", + "link": "https://learn.microsoft.com/azure/api-management/retry-policy", + "service": "APIM", "severity": "Medio", - "text": "Aproveche la replicación de entrada de datos para escenarios de recuperación ante desastres entre regiones", + "text": "Use directivas para agregar una dirección URL de back-end de conmutación por error y el almacenamiento en caché para reducir las llamadas con errores.", "waf": "Fiabilidad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Aplicación de las instrucciones de la prueba comparativa de seguridad en la nube de Microsoft relacionadas con el almacenamiento", - "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", - "service": "Azure Storage", - "severity": "Medio", - "text": "Tenga en cuenta la \"línea base de seguridad de Azure para el almacenamiento\"", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "De forma predeterminada, Azure Storage tiene una dirección IP pública y es accesible desde Internet. Los puntos de conexión privados permiten exponer de forma segura Azure Storage solo a los recursos de proceso de Azure que necesitan acceso, lo que elimina la exposición a la Internet pública", - "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", - "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", - "service": "Azure Storage", - "severity": "Alto", - "text": "Considere la posibilidad de usar puntos de conexión privados para Azure Storage", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Las cuentas de almacenamiento recién creadas se crean mediante el modelo de implementación de ARM, de modo que RBAC, auditoría, etc. están habilitados. Asegúrese de que no hay cuentas de almacenamiento antiguas con el modelo de implementación clásica en una suscripción", - "guid": "30e37c3e-2971-41b2-963c-eee079b598de", - "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", - "service": "Azure Storage", - "severity": "Medio", - "text": "Asegúrese de que las cuentas de almacenamiento más antiguas no usan el \"modelo de implementación clásica\"", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Aproveche Microsoft Defender para obtener información sobre la actividad sospechosa y los errores de configuración.", - "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", - "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", - "service": "Azure Storage", - "severity": "Alto", - "text": "Habilitación de Microsoft Defender para todas las cuentas de almacenamiento", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "El mecanismo de eliminación temporal permite recuperar blobs eliminados accidentalmente.", - "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", - "service": "Azure Storage", - "severity": "Medio", - "text": "Habilitación de la \"eliminación temporal\" para blobs", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere la posibilidad de deshabilitar de forma selectiva la \"eliminación temporal\" para determinados contenedores de blobs, por ejemplo, si la aplicación debe asegurarse de que la información eliminada se elimina inmediatamente, por ejemplo, por motivos de confidencialidad, privacidad o cumplimiento. ", - "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", - "service": "Azure Storage", - "severity": "Medio", - "text": "Deshabilitación de la \"eliminación temporal\" de blobs", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "La eliminación temporal de contenedores permite recuperar un contenedor después de que se haya eliminado, por ejemplo, recuperarse de una operación de eliminación accidental.", - "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", - "service": "Azure Storage", - "severity": "Alto", - "text": "Habilitación de la \"eliminación temporal\" para los contenedores", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere la posibilidad de deshabilitar de forma selectiva la \"eliminación temporal\" para determinados contenedores de blobs, por ejemplo, si la aplicación debe asegurarse de que la información eliminada se elimina inmediatamente, por ejemplo, por motivos de confidencialidad, privacidad o cumplimiento. ", - "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", - "service": "Azure Storage", - "severity": "Medio", - "text": "Deshabilitación de la \"eliminación temporal\" para contenedores", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Evita la eliminación accidental de una cuenta de almacenamiento, obligando al usuario a quitar primero el bloqueo de eliminación, antes de la eliminación", - "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", - "service": "Azure Storage", - "severity": "Alto", - "text": "Habilitación de bloqueos de recursos en cuentas de almacenamiento", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere la posibilidad de aplicar directivas de \"retención legal\" o \"retención basada en el tiempo\" para los blobs, de modo que sea imposible eliminar el blob, el contenedor o la cuenta de almacenamiento. Tenga en cuenta que 'imposible' en realidad significa 'imposible'; una vez que una cuenta de almacenamiento contiene un blob inmutable, la única manera de \"deshacerse\" de esa cuenta de almacenamiento es cancelando la suscripción de Azure.", - "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", - "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", - "service": "Azure Storage", - "severity": "Alto", - "text": "Considere la posibilidad de blobs inmutables", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere la posibilidad de deshabilitar el acceso HTTP/80 sin protección a la cuenta de almacenamiento, de modo que todas las transferencias de datos estén cifradas, protegidas por integridad y el servidor esté autenticado. ", - "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Azure Storage", - "severity": "Alto", - "text": "Requerir HTTPS, es decir, deshabilitar el puerto 80 en la cuenta de almacenamiento", - "waf": "Seguridad" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Al configurar un dominio personalizado (nombre de host) en una cuenta de almacenamiento, compruebe si necesita TLS/HTTPS; si es así, es posible que tenga que colocar Azure CDN delante de la cuenta de almacenamiento.", - "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", - "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", - "service": "Azure Storage", - "severity": "Alto", - "text": "Al aplicar HTTPS (deshabilitar HTTP), compruebe que no usa dominios personalizados (CNAME) para la cuenta de almacenamiento.", - "waf": "Seguridad" + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "8210699f-8d43-45c2-8f19-57e54134bd8f", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-log-event-hubs", + "service": "APIM", + "severity": "Bajo", + "text": "Si necesita iniciar sesión en niveles de alto rendimiento, tenga en cuenta la directiva de Event Hubs", + "waf": "Operaciones" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Requerir HTTPS cuando un cliente usa un token de SAS para acceder a los datos de blobs ayuda a minimizar el riesgo de pérdida de credenciales.", - "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "121bfc39-fa7b-4096-b93b-ab56c1bc0bed", + "link": "https://learn.microsoft.com/azure/api-management/api-management-sample-flexible-throttling", + "service": "APIM", "severity": "Medio", - "text": "Limitar los tokens de firma de acceso compartido (SAS) solo a las conexiones HTTPS", - "waf": "Seguridad" + "text": "Aplicación de directivas de limitación para controlar el número de solicitudes por segundo", + "training": "https://learn.microsoft.com/training/modules/protect-apis-on-api-management/", + "waf": "Rendimiento" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Los tokens de AAD deben favorecerse sobre las firmas de acceso compartido, siempre que sea posible", - "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", - "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", - "service": "Azure Storage", - "severity": "Alto", - "text": "Uso de tokens de Azure Active Directory (Azure AD) para el acceso a blobs", - "waf": "Seguridad" + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "bb5f356b-3daf-47a2-a9ee-867a8100bbd5", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-autoscale", + "service": "APIM", + "severity": "Medio", + "text": "Configurar el escalado automático para escalar horizontalmente el número de instancias cuando aumenta la carga", + "waf": "Rendimiento" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Al asignar un rol a un usuario, grupo o aplicación, conceda a esa entidad de seguridad solo los permisos necesarios para que pueda realizar sus tareas. Limitar el acceso a los recursos ayuda a evitar el uso indebido no intencionado y malintencionado de los datos.", - "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "84b94abb-59b6-4b9d-8587-3413669468e8", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-provision-self-hosted-gateway", + "service": "APIM", "severity": "Medio", - "text": "Privilegios mínimos en los permisos de IaM", - "waf": "Seguridad" + "text": "Implemente puertas de enlace autohospedadas en las que Azure no tenga una región cercana a las API de back-end.", + "waf": "Rendimiento" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Una SAS de delegación de usuarios está protegida con credenciales de Azure Active Directory (Azure AD) y también con los permisos especificados para la SAS. Una SAS de delegación de usuarios es análoga a una SAS de servicio en cuanto a su ámbito y función, pero ofrece ventajas de seguridad sobre la SAS de servicio. ", - "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", - "service": "Azure Storage", - "severity": "Alto", - "text": "Al usar SAS, prefiera \"SAS de delegación de usuarios\" en lugar de SAS basada en claves de cuenta de almacenamiento.", - "waf": "Seguridad" + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "1fe8db45-a017-4888-8c4d-4422583cfae0", + "link": "https://learn.microsoft.com/azure/api-management/upgrade-and-scale#upgrade-and-scale", + "service": "APIM", + "severity": "Medio", + "text": "Use el nivel premium para las cargas de trabajo de producción.", + "waf": "Fiabilidad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Las claves de la cuenta de almacenamiento (\"claves compartidas\") tienen muy pocas funcionalidades de auditoría. Si bien se puede monitorear quién o cuándo obtuvo una copia de las claves, una vez que las claves están en manos de varias personas, es imposible atribuir el uso a un usuario específico. Confiar únicamente en la autenticación de AAD facilita la vinculación del acceso al almacenamiento a un usuario. ", - "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", - "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "1b8d68a4-66cd-44d5-ba94-3ee94440e8d6", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region#-route-api-calls-to-regional-backend-services", + "service": "APIM", + "severity": "Medio", + "text": "En el modelo de varias regiones, use directivas para enrutar las solicitudes a los back-ends regionales en función de la disponibilidad o la latencia.", + "waf": "Fiabilidad" + }, + { + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "46f07d33-ef9a-44e8-8f98-67c097c5d8cd", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#api-management-limits", + "service": "APIM", "severity": "Alto", - "text": "Considere la posibilidad de deshabilitar las claves de la cuenta de almacenamiento, de modo que solo se admita el acceso a AAD (y la SAS de delegación de usuarios).", - "waf": "Seguridad" + "text": "Tenga en cuenta los límites de APIM", + "waf": "Fiabilidad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Use los datos del registro de actividad para identificar \"cuándo\", \"quién\", \"qué\" y \"cómo\" se está viendo o cambiando la seguridad de la cuenta de almacenamiento (es decir, claves de cuenta de almacenamiento, directivas de acceso, etc.).", - "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", - "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "10f58602-f0f9-4d77-972a-956f6e0f2600", + "link": "https://learn.microsoft.com/en-us/azure/api-management/self-hosted-gateway-overview", + "service": "APIM", "severity": "Alto", - "text": "Considere la posibilidad de usar Azure Monitor para auditar las operaciones del plano de control en la cuenta de almacenamiento", - "waf": "Seguridad" + "text": "Asegúrese de que las implementaciones de puerta de enlace autohospedadas sean resistentes.", + "waf": "Fiabilidad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Una directiva de expiración de claves le permite establecer un recordatorio para la rotación de las claves de acceso a la cuenta. El recordatorio se muestra si ha transcurrido el intervalo especificado y las teclas aún no se han girado.", - "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "7519e385-a88b-4d34-966b-6269d686e890", + "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", + "service": "APIM", "severity": "Medio", - "text": "Al usar claves de cuenta de almacenamiento, considere la posibilidad de habilitar una \"directiva de expiración de claves\"", - "waf": "Seguridad" + "text": "Uso de Azure Front Door delante de APIM para la implementación en varias regiones", + "waf": "Rendimiento" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Una directiva de expiración de SAS especifica un intervalo recomendado durante el cual la SAS es válida. Las directivas de expiración de SAS se aplican a una SAS de servicio o a una SAS de cuenta. Cuando un usuario genera una SAS de servicio o una SAS de cuenta con un intervalo de validez mayor que el intervalo recomendado, verá una advertencia.", - "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", - "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "cd45c90e-7690-4753-930b-bf290c69c074", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#virtual-network-integration", + "service": "APIM", "severity": "Medio", - "text": "Considere la posibilidad de configurar una directiva de expiración de SAS", + "text": "Implementación del servicio dentro de una red virtual (VNet)", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Las directivas de acceso almacenadas ofrecen la opción de revocar los permisos de una SAS de servicio sin tener que volver a generar las claves de la cuenta de almacenamiento. ", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "02661582-b3d1-48d1-9d7b-c6a918a0ca33", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", + "service": "APIM", "severity": "Medio", - "text": "Considere la posibilidad de vincular SAS a una directiva de acceso almacenada", + "text": "Implemente grupos de seguridad de red (NSG) en las subredes para restringir o supervisar el tráfico hacia/desde APIM.", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "67437a28-2721-4a2c-becd-caa54c8237a5", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", + "service": "APIM", "severity": "Medio", - "text": "Considere la posibilidad de configurar el repositorio de código fuente de la aplicación para detectar cadenas de conexión protegidas y claves de cuenta de almacenamiento.", + "text": "Implemente puntos de conexión privados para filtrar el tráfico entrante cuando APIM no se implemente en una red virtual.", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Lo ideal es que la aplicación use una identidad administrada para autenticarse en Azure Storage. Si esto no es posible, considere la posibilidad de tener la credencial de almacenamiento (cadena de conexión, clave de cuenta de almacenamiento, SAS, credencial de entidad de servicio) en Azure KeyVault o un servicio equivalente.", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "d698adbd-3288-44cb-b10a-9b572da395ae", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#disable-public-network-access", + "service": "APIM", "severity": "Alto", - "text": "Considere la posibilidad de almacenar cadenas de conexión en Azure KeyVault (en escenarios en los que las identidades administradas no son posibles)", + "text": "Deshabilitar el acceso a la red pública", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Use los tiempos de expiración a corto plazo en una SAS de servicio SAS ad hoc o en una SAS de cuenta. De esta manera, incluso si una SAS se ve comprometida, es válida solo por un corto tiempo. Esta práctica es especialmente importante si no puede hacer referencia a una directiva de acceso almacenada. Los tiempos de expiración a corto plazo también limitan la cantidad de datos que se pueden escribir en un blob al limitar el tiempo disponible para cargarlo.", - "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", - "severity": "Alto", - "text": "Esfuércese por obtener períodos de validez cortos para SAS ad-hoc", - "waf": "Seguridad" + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "0674d750-0c6f-4ac0-8717-ceec04d0bdbd", + "link": "https://learn.microsoft.com/azure/api-management/automation-manage-api-management", + "service": "APIM", + "severity": "Medio", + "text": "Simplifique la administración con scripts de automatización de PowerShell", + "waf": "Operaciones" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Al crear una SAS, sea lo más específico y restrictivo posible. Prefiera una SAS para un solo recurso y operación en lugar de una SAS que proporciona un acceso mucho más amplio.", - "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "c385bfcd-49fd-4786-81ba-cedbb4c57345", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/app-platform/api-management/platform-automation-and-devops#design-recommendations", + "service": "APIM", "severity": "Medio", - "text": "Aplicación de un ámbito limitado a una SAS", - "waf": "Seguridad" + "text": "Configure APIM a través de la infraestructura como código. Revise las prácticas recomendadas de DevOps desde el acelerador de zonas de aterrizaje de API de Cloud Adaption Framework", + "waf": "Operaciones" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Una SAS puede incluir parámetros en los que las direcciones IP de cliente o los intervalos de direcciones están autorizados a solicitar un recurso mediante la SAS. ", - "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", - "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "6c3a27c0-197f-426c-9ffa-86fed51d9ab6", + "link": "https://learn.microsoft.com/azure/api-management/visual-studio-code-tutorial", + "service": "APIM", "severity": "Medio", - "text": "Considere la posibilidad de definir el ámbito de SAS en una dirección IP de cliente específica, siempre que sea posible", - "waf": "Seguridad" + "text": "Promover el uso de la extensión APIM de Visual Studio Code para un desarrollo de API más rápido", + "waf": "Operaciones" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Una SAS no puede restringir la cantidad de datos que carga un cliente; Dado el modelo de precios de la cantidad de almacenamiento a lo largo del tiempo, podría tener sentido validar si los clientes cargaron contenido de gran tamaño malintencionado.", - "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", - "service": "Azure Storage", - "severity": "Bajo", - "text": "Considere la posibilidad de comprobar los datos cargados, después de que los clientes hayan usado una SAS para cargar un archivo. ", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "354f1c03-8112-4965-85ad-c0074bddf231", + "link": "https://learn.microsoft.com/azure/api-management/devops-api-development-templates", + "service": "APIM", + "severity": "Medio", + "text": "Implemente DevOps y CI/CD en su flujo de trabajo", + "waf": "Operaciones" + }, + { + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "b6439493-426a-45f3-9697-cf65baee208d", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates-for-clients", + "service": "APIM", + "severity": "Medio", + "text": "API seguras mediante la autenticación de certificados de cliente", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Al acceder a Blob Storage a través de SFTP mediante una \"cuenta de usuario local\", no se aplican los controles RBAC \"habituales\". El acceso a blobs a través de NFS o REST puede ser más restrictivo que el acceso SFTP. Desafortunadamente, a partir de principios de 2023, los usuarios locales son la única forma de administración de identidades que actualmente se admite para el punto de conexión SFTP", - "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", - "service": "Azure Storage", - "severity": "Alto", - "text": "SFTP: Limite la cantidad de \"usuarios locales\" para el acceso SFTP y audite si el acceso es necesario a lo largo del tiempo.", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "2a67d143-1033-4c0a-8732-680896478f08", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates", + "service": "APIM", + "severity": "Medio", + "text": "Servicios de back-end seguros mediante la autenticación de certificados de cliente", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "074435f5-4a46-41ac-b521-d6114cb5d845", + "link": "https://learn.microsoft.com/azure/api-management/mitigate-owasp-api-threats", + "service": "APIM", "severity": "Medio", - "text": "SFTP: El punto de conexión SFTP no admite ACL similares a POSIX.", + "text": "Revise el artículo \"Recomendaciones para mitigar las 10 principales amenazas de seguridad de la API de OWASP\" y compruebe qué se aplica a sus API", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "El almacenamiento es compatible con CORS (Cross-Origin Resource Sharing), es decir, una función HTTP que permite a las aplicaciones web de un dominio diferente relajar la política del mismo origen. Al habilitar CORS, mantenga CorsRules con el mínimo privilegio.", - "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", - "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", - "service": "Azure Storage", - "severity": "Alto", - "text": "Evite las políticas de CORS demasiado amplias", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", + "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", + "service": "APIM", + "severity": "Medio", + "text": "Utilice la función Autorizaciones para simplificar la administración del token de OAuth 2.0 para las API de back-end", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Los datos en reposo siempre están cifrados en el lado del servidor y, además, también pueden estar cifrados en el lado del cliente. El cifrado del lado del servidor puede realizarse mediante una clave administrada por la plataforma (predeterminada) o una clave administrada por el cliente. El cifrado del lado cliente puede producirse haciendo que el cliente proporcione una clave de cifrado y descifrado por blob a Azure Storage o controlando completamente el cifrado en el lado cliente. por lo tanto, no depende en absoluto de Azure Storage para obtener garantías de confidencialidad.", - "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", - "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "2deee033-b906-4bc2-9f26-c8d3699fe091", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-manage-protocols-ciphers", + "service": "APIM", "severity": "Alto", - "text": "Determine cómo se deben cifrar los datos en reposo. Comprender el modelo de subprocesos para los datos.", + "text": "Utilice la versión más reciente de TLS al cifrar la información en tránsito. Deshabilite los protocolos y cifrados obsoletos e innecesarios cuando sea posible.", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", - "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", - "service": "Azure Storage", - "severity": "Medio", - "text": "Determine qué cifrado de plataforma se debe usar o si se debe usar.", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "f8af3d94-1d2b-4070-846f-849197524258", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#im-8-restrict-the-exposure-of-credential-and-secrets", + "service": "APIM", + "severity": "Alto", + "text": "Asegúrese de que los secretos (valores con nombre) se almacenan en Azure Key Vault para que se pueda acceder a ellos y actualizarlos de forma segura", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", - "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "791abd8b-7706-4e31-9569-afefde724be3", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#managed-identities", + "service": "APIM", "severity": "Medio", - "text": "Determine qué cifrado del lado del cliente se debe usar o si.", + "text": "Uso de identidades administradas para autenticarse en otros recursos de Azure siempre que sea posible", "waf": "Seguridad" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Aproveche el Explorador de Resource Graph (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) para buscar cuentas de almacenamiento que permitan el acceso anónimo a blobs.", - "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", - "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", - "service": "Azure Storage", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "220c4ca6-6688-476b-b2b5-425a78e6fb87", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", + "service": "APIM", "severity": "Alto", - "text": "Considere si se necesita acceso público a blobs o si se puede deshabilitar para determinadas cuentas de almacenamiento. ", + "text": "Uso del firewall de aplicaciones web (WAF) mediante la implementación de Application Gateway delante de APIM", "waf": "Seguridad" }, + { + "arm-service": "Microsoft.DBforMySQL/servers", + "checklist": "MySQL Review Checklist", + "guid": "388c3e25-e800-4ad2-9df3-f3d6ae1050b7", + "link": "https://learn.microsoft.com/azure/mysql/flexible-server/overview", + "service": "Azure MySQL", + "severity": "Medio", + "text": "Aproveche el servidor flexible", + "waf": "Fiabilidad" + }, + { + "arm-service": "Microsoft.DBforMySQL/servers", + "checklist": "MySQL Review Checklist", + "guid": "de3aad1e-8c38-4ec9-9666-7313c005674b", + "link": "https://learn.microsoft.com/azure/mysql/flexible-server/overview#high-availability-within-and-across-availability-zones", + "service": "Azure MySQL", + "severity": "Alto", + "text": "Aproveche las zonas de disponibilidad cuando corresponda regionalmente", + "waf": "Fiabilidad" + }, + { + "arm-service": "Microsoft.DBforMySQL/servers", + "checklist": "MySQL Review Checklist", + "guid": "1e944a45-9c37-43e7-bd61-623b365a917e", + "link": "https://learn.microsoft.com/azure/mysql/flexible-server/overview#setup-hybrid-or-multi-cloud-data-synchronization-with-data-in-replication", + "service": "Azure MySQL", + "severity": "Medio", + "text": "Aproveche la replicación de entrada de datos para escenarios de recuperación ante desastres entre regiones", + "waf": "Fiabilidad" + }, { "arm-service": "Microsoft.Insights/components", "checklist": "Cost Optimization Checklist", @@ -8932,6 +9377,208 @@ "text": "Obtenga información sobre cómo conmutar por recuperación después de una conmutación por error.", "waf": "Fiabilidad" }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deshabilite la exportación de imágenes para evitar la exfiltración de datos. Tenga en cuenta que esto evitará la importación de imágenes a otra instancia de ACR.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "Alto", + "text": "Deshabilitación de la exportación de imágenes de Azure Container Registry", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Habilite la visibilidad del cumplimiento de auditorías mediante la habilitación de Azure Policy para Azure Container Registry", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "Alto", + "text": "Habilitación de Azure Policies para Azure Container Registry", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Key Vault (AKV) se usa para almacenar una clave de firma que se puede usar mediante la notación con el complemento de notación AKV (azure-kv) para firmar y comprobar imágenes de contenedor y otros artefactos. Azure Container Registry (ACR) le permite adjuntar estas firmas mediante el ?az?or?oras? Comandos de la CLI.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "Alto", + "text": "Firmar y verificar contenedores con notación (Notary v2)", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry cifra automáticamente las imágenes y otros artefactos que almacene. De forma predeterminada, Azure cifra automáticamente el contenido del Registro en reposo mediante claves administradas por el servicio. Mediante el uso de una clave administrada por el cliente, puede complementar el cifrado predeterminado con una capa de cifrado adicional.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "Medio", + "text": "Cifrar el registro con una clave administrada por el cliente", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Uso de identidades administradas para proteger el acceso ACRPull/Push RBAC desde aplicaciones cliente", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "Alto", + "text": "Uso de identidades administradas para conectarse en lugar de entidades de servicio", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "La cuenta de administrador local está deshabilitada de forma predeterminada y no debe estar habilitada. En su lugar, use métodos de acceso basados en token o RBAC", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "Alto", + "text": "Deshabilitación de la autenticación local para el acceso al plano de administración", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deshabilite la cuenta de administrador y asigne roles de RBAC a las entidades de seguridad para las operaciones de extracción/inserción de ACR", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "Alto", + "text": "Asigne roles RBAC AcrPull y AcrPush en lugar de conceder acceso administrativo a las entidades de identidad", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deshabilitar el acceso anónimo de extracción/inserción", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "Medio", + "text": "Deshabilitar el acceso de extracción anónimo", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "La autenticación de token no admite la asignación a una entidad de seguridad de AAD. Los tokens proporcionados pueden ser utilizados por cualquier persona que pueda acceder al token", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "Alto", + "text": "Deshabilitación de tokens de acceso con ámbito de repositorio", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Implementación de imágenes de contenedor en un ACR detrás de un punto de conexión privado dentro de una red de confianza", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "Alto", + "text": "Implementación de imágenes desde un entorno de confianza", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Solo los tokens con una audiencia de ACR se pueden usar para la autenticación. Se usa al habilitar directivas de acceso condicional para ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "Medio", + "text": "Deshabilitación de tokens de audiencia de Azure ARM para la autenticación", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Configure una configuración de diagnóstico para enviar 'repositoryEvents' y 'LoginEvents' a Log Analytics como destino central para el registro y la supervisión. Esto le permite supervisar la actividad del plano de control en el propio recurso ACR.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "Medio", + "text": "Habilitación del registro de diagnósticos", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "El servicio admite la deshabilitación del acceso a la red pública mediante la regla de filtrado de ACL de IP de nivel de servicio (no NSG ni Azure Firewall) o mediante un conmutador de alternancia \"Deshabilitar el acceso a la red pública\"", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "Medio", + "text": "Controle el acceso a la red entrante con Private Link", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Deshabilitar el acceso a la red pública si el acceso a la red entrante está protegido mediante Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "Medio", + "text": "Deshabilitar el acceso a la red pública", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Solo la SKU ACR Premium admite el acceso a Private Link", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "Medio", + "text": "Uso de una SKU de Azure Container Registry que admita Private Link (SKU Premium)", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Defender para contenedores o un servicio equivalente debe usarse para examinar las imágenes de contenedor en busca de vulnerabilidades", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "Bajo", + "text": "Habilitación de Defender para contenedores para examinar Azure Container Registry en busca de vulnerabilidades", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Implemente código de confianza que se validó y analizó en busca de vulnerabilidades de acuerdo con las prácticas de DevSecOps.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "severity": "Medio", + "text": "Implementación de imágenes de contenedor validadas", + "waf": "Seguridad" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Utilice las versiones más recientes de las plataformas, lenguajes de programación, protocolos y marcos compatibles.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "Alto", + "text": "Utilice plataformas, lenguajes, protocolos y marcos actualizados", + "waf": "Seguridad" + }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", @@ -10400,46 +11047,6 @@ "text": "Habilitar eliminación temporal", "waf": "Fiabilidad" }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "Alto", - "text": "Habilite la redundancia de zona para Azure Cache for Redis. Azure Cache for Redis admite configuraciones con redundancia de zona en los niveles Premium y Enterprise. Una caché con redundancia de zona puede colocar sus nodos en diferentes zonas de disponibilidad de Azure en la misma región. Elimina la interrupción del centro de datos o de la zona de disponibilidad como único punto de error y aumenta la disponibilidad general de la memoria caché.", - "waf": "Fiabilidad" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", - "severity": "Medio", - "text": "Configure la persistencia de datos para una instancia de Azure Cache for Redis. Dado que los datos de caché se almacenan en la memoria, un error poco frecuente y no planeado de varios nodos puede hacer que se eliminen todos los datos. Para evitar la pérdida completa de datos, la persistencia de Redis permite tomar instantáneas periódicas de los datos en memoria y almacenarlas en la cuenta de almacenamiento.", - "waf": "Fiabilidad" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", - "severity": "Medio", - "text": "Use una cuenta de almacenamiento con redundancia geográfica para conservar los datos de Azure Cache for Redis o con redundancia zonal donde la redundancia geográfica no esté disponible", - "waf": "Fiabilidad" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", - "severity": "Medio", - "text": "Configure la replicación geográfica pasiva para instancias de Azure Cache for Redis Premium. La replicación geográfica es un mecanismo para vincular dos o más instancias de Azure Cache for Redis, que normalmente abarcan dos regiones de Azure. La replicación geográfica está diseñada principalmente para la recuperación ante desastres entre regiones. Dos instancias de caché de nivel Premium se conectan a través de la replicación geográfica de una manera que proporciona lecturas y escrituras en la caché principal, y esos datos se replican en la caché secundaria.", - "waf": "Fiabilidad" - }, { "arm-service": "Microsoft.Devices/provisioningServices", "checklist": "Device Provisioning Service Review", @@ -10670,7 +11277,7 @@ ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/waf_checklist.ja.json b/checklists/waf_checklist.ja.json index 15eefbd5..41e77755 100644 --- a/checklists/waf_checklist.ja.json +++ b/checklists/waf_checklist.ja.json @@ -3064,1066 +3064,698 @@ "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ストレージに関連する Microsoft クラウド セキュリティ ベンチマークのガイダンスを適用する", - "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", - "service": "Azure Storage", - "severity": "中程度", - "text": "\"ストレージの Azure セキュリティ ベースライン\" を検討する", - "waf": "安全" + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "4238f409-2ea0-43be-a06b-2a993c98aa7b", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", + "service": "Azure Functions", + "severity": "高い", + "text": "ビジネスとSLOの要件に基づいて適切な関数ホスティングプランを選択します", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "既定では、Azure Storage にはパブリック IP アドレスがあり、インターネットにアクセス可能です。プライベート エンドポイントを使用すると、アクセスが必要な Azure コンピューティング リソースにのみ Azure Storage を安全に公開できるため、パブリック インターネットへの露出を排除できます", - "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", - "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", - "service": "Azure Storage", + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "a9808100-d640-4f77-ac56-1ec0600f6752", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", + "service": "Azure Functions", "severity": "高い", - "text": "Azure Storage にプライベート エンドポイントを使用することを検討する", - "waf": "安全" + "text": "リージョンで適用可能な場合は Availability Zones を活用します (従量課金レベルでは使用できません)", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "新しく作成されたストレージ アカウントは、RBAC や監査などがすべて有効になるように、ARM デプロイ モデルを使用して作成されます。サブスクリプションにクラシック デプロイ モデルの古いストレージ アカウントがないことを確認する", - "guid": "30e37c3e-2971-41b2-963c-eee079b598de", - "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", - "service": "Azure Storage", + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "5969d03e-eacf-4042-b127-73c55e3575fa", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-functions?tabs=azure-portal#cross-region-disaster-recovery-and-business-continuity", + "service": "Azure Functions", "severity": "中程度", - "text": "古いストレージ アカウントで \"クラシック デプロイ モデル\" が使用されていないことを確認する", - "waf": "安全" + "text": "重要なワークロードに対するリージョン間 DR 戦略を検討する", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Microsoft Defender を活用して、不審なアクティビティや構成ミスについて学習します。", - "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", - "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", - "service": "Azure Storage", + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "47a0aae0-d8a0-43b1-9791-e934dee3754c", + "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", + "service": "Azure Functions", "severity": "高い", - "text": "すべてのストレージ アカウントに対して Microsoft Defender を有効にする", - "waf": "安全" + "text": "分離環境にデプロイする場合は、App Service Environment (ASE) v3 を使用するか、それらに移行します", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "論理的な削除メカニズムを使用すると、誤って削除された BLOB を回復できます。", - "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "17232891-f89f-4eaa-90f1-3b34bf798ed5", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", + "service": "Azure Functions", + "severity": "高い", + "text": "App Service プランで実行されているすべての関数アプリで \"Always On\" が有効になっていることを確認する", + "waf": "確実" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "40a325c2-7c0e-49e6-86d8-c273b4dc21ba", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations?tabs=azure-cli#shared-storage-accounts", + "service": "Azure Functions", "severity": "中程度", - "text": "BLOB の \"論理的な削除\" を有効にする", - "waf": "安全" + "text": "関数アプリを独自のストレージ アカウントにペアリングします。Function Apps のストレージ アカウントは、緊密に結合されていない限り、再利用しないようにしてください", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "たとえば、機密性、プライバシー、コンプライアンス上の理由などから、削除された情報がすぐに削除されるようにアプリケーションで確認する必要がある場合など、特定の BLOB コンテナーに対して \"論理的な削除\" を選択的に無効にすることを検討してください。", - "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", - "service": "Azure Storage", + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "bb42650c-257d-4cb0-822a-131138b8e6f0", + "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", + "service": "Azure Functions", "severity": "中程度", - "text": "BLOB の '論理的な削除' を無効にする", - "waf": "安全" + "text": "Azure DevOps または GitHub を活用して CI/CD を合理化し、関数アプリのコードを保護します", + "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "コンテナーの論理的な削除を使用すると、コンテナーが削除された後に回復できます (たとえば、偶発的な削除操作から回復します)。", - "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "ac1d6380-f866-4bbd-a9b4-b1ee5d7908b8", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#availability-zones", + "service": "IoT", "severity": "高い", - "text": "コンテナーの \"論理的な削除\" を有効にする", - "waf": "安全" + "text": "Availability Zones (リージョンで適用可能な場合) を活用する (これは自動的に有効になります)", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "たとえば、機密性、プライバシー、コンプライアンス上の理由などから、削除された情報がすぐに削除されるようにアプリケーションで確認する必要がある場合など、特定の BLOB コンテナーに対して \"論理的な削除\" を選択的に無効にすることを検討してください。", - "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "35f651e8-0124-4ef7-8c57-658e38609e6e", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", + "service": "IoT", "severity": "中程度", - "text": "コンテナーの \"論理的な削除\" を無効にする", - "waf": "安全" + "text": "Microsoft が開始するフェールオーバーに注意してください。これらは、まれに、影響を受けるリージョンから対応する geo ペア リージョンにすべての IoT ハブをフェールオーバーするために Microsoft によって実行されます。", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "削除前に削除ロックを最初に解除するようにユーザーに強制することで、ストレージ アカウントが誤って削除されないようにします", - "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "4ed3e490-dc06-4a1e-b467-5d0239d85540", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#cross-region-dr", + "service": "IoT", "severity": "高い", - "text": "ストレージ アカウントでのリソース ロックの有効化", - "waf": "安全" + "text": "重要なワークロードに対するリージョン間 DR 戦略を検討する", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "BLOB の \"訴訟ホールド\" または \"時間ベースの保持\" ポリシーを検討して、BLOB、コンテナー、またはストレージ アカウントを削除できないようにします。「不可能」は実際には「不可能」を意味することに注意してください。ストレージ アカウントに不変の BLOB が含まれる場合、そのストレージ アカウントを \"取り除く\" 唯一の方法は、Azure サブスクリプションを取り消すことです。", - "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", - "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "a11ecab0-db47-46f7-9aa7-17764e7e45a1", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", + "service": "IoT", "severity": "高い", - "text": "不変の BLOB を検討する", - "waf": "安全" + "text": "手動フェールオーバーをトリガーする方法を学習します。", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ストレージ アカウントへの保護されていない HTTP/80 アクセスを無効にして、すべてのデータ転送が暗号化され、整合性が保護され、サーバーが認証されるようにすることを検討してください。", - "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "f9db8dfb-1194-460b-aedd-34dd6a69db22", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#failback", + "service": "IoT", "severity": "高い", - "text": "HTTPS を要求する (つまり、ストレージ アカウントのポート 80 を無効にする)", - "waf": "安全" + "text": "フェールオーバー後にフェールバックする方法を学習します。", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ストレージ アカウントでカスタム ドメイン (ホスト名) を構成する場合は、TLS/HTTPS が必要かどうかを確認します。その場合は、ストレージ アカウントの前に Azure CDN を配置する必要があります。", - "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", - "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", - "service": "Azure Storage", - "severity": "高い", - "text": "HTTPS を適用する (HTTP を無効にする) 場合は、ストレージ アカウントにカスタム ドメイン (CNAME) を使用していないことを確認します。", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant", + "guid": "553585a6-abe0-11ed-afa1-0242ac120002", + "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "service": "App Gateway", + "severity": "中程度", + "text": "Application Gateway v2 SKU を使用していることを確認する", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "クライアントが SAS トークンを使用して BLOB データにアクセスするときに HTTPS を要求すると、資格情報が失われるリスクを最小限に抑えることができます。", - "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.Network/loadBalancers", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", + "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", + "service": "Load Balancer", "severity": "中程度", - "text": "Shared Access Signature (SAS) トークンを HTTPS 接続のみに制限する", + "text": "Azure Load Balancers に Standard SKU を使用していることを確認します", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "AAD トークンは、可能な限り、共有アクセス署名よりも優先する必要があります", - "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", - "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", - "service": "Azure Storage", - "severity": "高い", - "text": "BLOB アクセスに Azure Active Directory (Azure AD) トークンを使用する", + "arm-service": "Microsoft.Network/loadBalancers", + "checklist": "Azure Application Delivery Networking", + "guid": "9432621a-8397-4654-a882-5bc856b7ef83", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-standard-availability-zones", + "service": "Load Balancer", + "severity": "中程度", + "text": "Load Balancer フロントエンドの IP アドレスがゾーン冗長であることを確認します (ゾーン フロントエンドが必要な場合を除く)。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ユーザー、グループ、またはアプリケーションにロールを割り当てる場合は、タスクの実行に必要なアクセス許可のみをセキュリティ プリンシパルに付与します。リソースへのアクセスを制限することで、意図しないデータの誤用と悪意のあるデータの誤用の両方を防ぐことができます。", - "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", - "service": "Azure Storage", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant", + "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", + "service": "App Gateway", "severity": "中程度", - "text": "IaM アクセス許可の最小特権", + "text": "Application Gateways v2 は、IP プレフィックスが /24 以上のサブネットにデプロイする必要があります", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ユーザー委任 SAS は、Azure Active Directory (Azure AD) 資格情報と、SAS に指定されたアクセス許可によってセキュリティで保護されます。ユーザー委任 SAS は、そのスコープと機能の点でサービス SAS に似ていますが、サービス SAS よりもセキュリティ上の利点があります。", - "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", - "service": "Azure Storage", - "severity": "高い", - "text": "SAS を使用する場合は、ストレージ アカウント キー ベースの SAS よりも \"ユーザー委任 SAS\" を優先します。", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "description": "リバースプロキシの管理全般、特にWAFの管理は、ネットワーキングよりもアプリケーションに近いため、アプリと同じサブスクリプションに属します。Application Gateway と WAF を接続サブスクリプションに一元化することは、1 つのチームによって管理されている場合は問題ない可能性があります。", + "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "App Gateway", + "severity": "中程度", + "text": "ランディング ゾーン仮想ネットワーク内の受信 HTTP(S) 接続のプロキシに使用される Azure Application Gateway v2 またはパートナー NVA と、それらがセキュリティ保護しているアプリをデプロイします。", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ストレージ アカウント キー (\"共有キー\") には、監査機能がほとんどありません。誰がいつキーのコピーを取得したかを監視できますが、キーが複数の人の手に渡ると、使用状況を特定のユーザーに帰属させることは不可能です。AAD 認証のみに依存することで、ストレージへのアクセスをユーザーに結び付けやすくなります。", - "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", - "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", - "service": "Azure Storage", - "severity": "高い", - "text": "ストレージ アカウント キーを無効にして、AAD アクセス (およびユーザー委任 SAS) のみがサポートされるようにすることを検討してください。", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "アクティビティ ログ データを使用して、ストレージ アカウントのセキュリティ (ストレージ アカウント キー、アクセス ポリシーなど) が \"いつ、誰が、何を、\"どのように\" 表示または変更されているかを特定します。", - "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", - "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", - "service": "Azure Storage", - "severity": "高い", - "text": "Azure Monitor を使用して、ストレージ アカウントに対するコントロール プレーン操作を監査することを検討してください", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "キーの有効期限ポリシーを使用すると、アカウントアクセスキーのローテーションのリマインダーを設定できます。リマインダーは、指定した間隔が経過し、キーがまだローテーションされていない場合に表示されます。", - "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", - "service": "Azure Storage", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "f109e1f3-c79b-4f14-82de-6b5c22314d08", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "App Gateway", "severity": "中程度", - "text": "ストレージ アカウント キーを使用する場合は、\"キーの有効期限ポリシー\" を有効にすることを検討してください", + "text": "アプリケーション ランディング ゾーン内のすべてのパブリック IP アドレスに対して、DDoS ネットワークまたは IP 保護プランを使用します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS 有効期限ポリシーでは、SAS が有効である推奨間隔を指定します。SAS 有効期限ポリシーは、サービス SAS またはアカウント SAS に適用されます。ユーザーがサービス SAS またはアカウント SAS を、推奨間隔よりも長い有効期間で生成すると、警告が表示されます。", - "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", - "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", - "service": "Azure Storage", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant", + "guid": "135bf4ac-f9db-461f-b76b-2ee9e30b12c0", + "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant", + "service": "App Gateway", "severity": "中程度", - "text": "SAS 有効期限ポリシーの構成を検討する", - "waf": "安全" + "text": "自動スケールは、最小インスタンス数が 2 になるように構成します。", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "保存されているアクセス ポリシーを使用すると、ストレージ アカウント キーを再生成することなく、サービス SAS のアクセス許可を取り消すことができます。", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", - "service": "Azure Storage", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant", + "guid": "060c6964-52b5-48db-af8b-83e4b2d85349", + "link": "https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2", + "service": "App Gateway", "severity": "中程度", - "text": "保存されているアクセス ポリシーに SAS をリンクすることを検討する", - "waf": "安全" + "text": "Application Gateway を複数の可用性ゾーンにデプロイする", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", - "service": "Azure Storage", + "arm-service": "microsoft.network/frontdoors", + "checklist": "Azure Application Delivery Networking", + "guid": "3f29812b-2363-4cef-b179-b599de0d5973", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "service": "Front Door", "severity": "中程度", - "text": "チェックインされた接続文字列とストレージ アカウント キーを検出するようにアプリケーションのソース コード リポジトリを構成することを検討してください。", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "理想的には、アプリケーションでマネージド ID を使用して Azure Storage に対する認証を行う必要があります。それが不可能な場合は、ストレージ資格情報 (接続文字列、ストレージ アカウント キー、SAS、サービス プリンシパル資格情報) を Azure KeyVault または同等のサービスに用意することを検討してください。", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", - "service": "Azure Storage", - "severity": "高い", - "text": "接続文字列を Azure KeyVault に格納することを検討する (マネージド ID が不可能なシナリオの場合)", + "text": "Front Door と Application Gateway を使用して HTTP/S アプリを保護する場合は、Front Door で WAF ポリシーを使用します。Application Gateway をロックダウンして、Front Door からのトラフィックのみを受信します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "アドホック SAS サービス SAS またはアカウント SAS で、有効期限が近づいています。このように、SAS が侵害された場合でも、有効期間は短時間です。この方法は、保存されているアクセス ポリシーを参照できない場合に特に重要です。また、有効期限が近いと、BLOB にアップロードできる時間が制限されるため、BLOB に書き込めるデータの量も制限されます。", - "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", + "ammp": true, + "arm-service": "microsoft.network/trafficManagerProfiles", + "checklist": "Azure Application Delivery Networking", + "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "Traffic Manager", "severity": "高い", - "text": "アドホックSASの有効期間を短くする", - "waf": "安全" + "text": "Traffic Manager を使用して、HTTP/S 以外のプロトコルにまたがるグローバル アプリを配信します。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS を作成するときは、できるだけ具体的かつ制限的にしてください。1 つのリソースと操作には、より広範なアクセスを提供する SAS よりも SAS を優先します。", - "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", - "severity": "中程度", - "text": "SAS に狭いスコープを適用する", + "checklist": "Azure Application Delivery Networking", + "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "service": "Entra", + "severity": "低い", + "text": "ユーザーが内部アプリケーションへのアクセスのみを必要とする場合、Microsoft Entra ID アプリケーション プロキシは Azure Virtual Desktop (AVD) の代替手段として検討されていますか?", + "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS には、SAS を使用してリソースを要求する権限をクライアント IP アドレスまたはアドレス範囲に与えるパラメーターを含めることができます。", - "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", - "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", - "service": "Azure Storage", + "checklist": "Azure Application Delivery Networking", + "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", + "service": "Entra", "severity": "中程度", - "text": "可能な限り、SAS のスコープを特定のクライアント IP アドレスに設定することを検討してください", + "text": "ネットワーク内の着信接続用に開かれるファイアウォール ポートの数を減らすには、Microsoft Entra ID アプリケーション プロキシを使用して、リモート ユーザーに内部アプリケーションへの安全で認証されたアクセスを提供することを検討してください。", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS は、クライアントがアップロードするデータの量を制限できません。時間の経過に伴うストレージ容量の価格モデルを考えると、クライアントが悪意を持って大きなコンテンツをアップロードしたかどうかを検証することは理にかなっているかもしれません。", - "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", - "service": "Azure Storage", - "severity": "低い", - "text": "クライアントが SAS を使用してファイルをアップロードした後、アップロードされたデータを確認することを検討してください。", - "waf": "安全" + "ammp": true, + "arm-service": "Microsoft.Network/loadBalancers", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant", + "guid": "97a2fd46-64b0-1dfa-b72d-9c8869496d75", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "service": "Load Balancer", + "severity": "高い", + "text": "Load Balancer のアウトバウンド規則の代わりに Azure NAT Gateway を使用して SNAT のスケーラビリティを向上させる", + "waf": "確実" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "\"ローカル ユーザー アカウント\" を使用して SFTP 経由で BLOB ストレージにアクセスする場合、\"通常の\" RBAC 制御は適用されません。NFS または REST 経由の BLOB アクセスは、SFTP アクセスよりも制限が厳しい場合があります。残念ながら、2023 年初頭の時点で、SFTP エンドポイントで現在サポートされている ID 管理の形式はローカル ユーザーだけです", - "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", - "service": "Azure Storage", + "ammp": true, + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "graph": "resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id", + "guid": "2f8e81eb-8e68-4026-8b1f-70f9b05f7cf9", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection", + "service": "App Gateway", "severity": "高い", - "text": "SFTP: SFTPアクセスの「ローカルユーザー」の数を制限し、時間の経過とともにアクセスが必要かどうかを監査します。", + "text": "Azure Application Gateway WAF ボット保護ルール セットを有効にします。ボット ルールは、良いボットと悪いボットを検出します。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", - "service": "Azure Storage", - "severity": "中程度", - "text": "SFTP: SFTP エンドポイントは、POSIX ライクな ACL をサポートしていません。", + "ammp": true, + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "8ea8e0d4-84e8-4b33-aeab-493f6391b4d6", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", + "service": "App Gateway", + "severity": "高い", + "text": "Azure Application Gateway WAF ポリシーで要求本文の検査機能が有効になっているかどうかを確認します。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "ストレージは、CORS (Cross-Origin Resource Sharing)、つまり、異なるドメインの Web アプリが同一生成元ポリシーを緩めることを可能にする HTTP 機能をサポートしています。CORS を有効にする場合は、CorsRules を最小の特権に保ちます。", - "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", - "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", - "service": "Azure Storage", + "ammp": true, + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "a4dd86d3-5ffa-408c-b660-cce073d085b8", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#tune-your-waf", + "service": "App Gateway", "severity": "高い", - "text": "過度に広範な CORS ポリシーを避ける", + "text": "ワークロードの検出モードで Azure Application Gateway WAF を調整します。誤検出を減らします。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "保存データは常にサーバー側で暗号化され、さらにクライアント側でも暗号化される場合があります。サーバー側の暗号化は、プラットフォーム マネージド キー (既定) またはカスタマー マネージド キーを使用して行われる場合があります。クライアント側の暗号化は、クライアントが BLOB ごとに暗号化/暗号化解除キーを Azure Storage に提供するか、クライアント側で暗号化を完全に処理することによって行われます。そのため、機密性の保証を Azure Storage にまったく依存しません。", - "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", - "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", - "service": "Azure Storage", + "ammp": true, + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "baf8e317-2397-4d49-b3d1-0dcc16d8778d", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/policy-overview?source=recommendations", + "service": "App Gateway", "severity": "高い", - "text": "保存データの暗号化方法を決定します。データのスレッド モデルを理解します。", + "text": "Application Gateway の WAF ポリシーを \"防止\" モードでデプロイします。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", - "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", - "service": "Azure Storage", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "43fae595-8a32-4299-a69e-0f32c454dcc9", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/rate-limiting-overview", + "service": "App Gateway", "severity": "中程度", - "text": "どのプラットフォーム暗号化を使用するか、または使用するかを決定します。", + "text": "Azure Application Gateway WAF にレート制限を追加します。レート制限は、クライアントが誤ってまたは意図的に短時間に大量のトラフィックを送信するのをブロックします。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", - "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", - "service": "Azure Storage", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "041e0ad8-7b12-4694-a0b7-a0e25ee2470f", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/rate-limiting-overview#rate-limiting-details", + "service": "App Gateway", "severity": "中程度", - "text": "クライアント側の暗号化を使用するかどうかを決定します。", + "text": "Azure Application Gateway WAF のレート制限には高いしきい値を使用します。レート制限のしきい値を高くすると、正当なトラフィックのブロックを回避しながら、インフラストラクチャを圧倒する可能性のある非常に多くのリクエストに対する保護を提供します。", "waf": "安全" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Resource Graph エクスプローラー (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) を利用して、匿名 BLOB アクセスを許可するストレージ アカウントを検索します。", - "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", - "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", - "service": "Azure Storage", - "severity": "高い", - "text": "パブリック BLOB アクセスが必要かどうか、または特定のストレージ アカウントに対して無効にできるかどうかを検討します。", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "99937189-ff78-492a-b9ca-18d828d82b37", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#geo-filtering-best-practices", + "service": "App Gateway", + "severity": "低い", + "text": "すべての地理的地域からのトラフィックを想定していない場合は、geo フィルタを使用して、想定外の国からのトラフィックをブロックします。", "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "4238f409-2ea0-43be-a06b-2a993c98aa7b", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", - "service": "Azure Functions", - "severity": "高い", - "text": "ビジネスとSLOの要件に基づいて適切な関数ホスティングプランを選択します", - "waf": "確実" - }, - { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "a9808100-d640-4f77-ac56-1ec0600f6752", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", - "service": "Azure Functions", - "severity": "高い", - "text": "リージョンで適用可能な場合は Availability Zones を活用します (従量課金レベルでは使用できません)", - "waf": "確実" - }, - { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "5969d03e-eacf-4042-b127-73c55e3575fa", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-functions?tabs=azure-portal#cross-region-disaster-recovery-and-business-continuity", - "service": "Azure Functions", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "349a15c1-52f4-4319-9078-3895d95ecafd", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/geomatch-custom-rules", + "service": "App Gateway", "severity": "中程度", - "text": "重要なワークロードに対するリージョン間 DR 戦略を検討する", - "waf": "確実" - }, - { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "47a0aae0-d8a0-43b1-9791-e934dee3754c", - "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", - "service": "Azure Functions", - "severity": "高い", - "text": "分離環境にデプロイする場合は、App Service Environment (ASE) v3 を使用するか、それらに移行します", - "waf": "確実" + "text": "Azure Application Gateway WAF を使用してトラフィックを geo フィルタリングする場合は、不明な (ZZ) 場所を指定します。IP アドレスを地理的に一致できない場合に、正当な要求を誤ってブロックしないようにします。", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "17232891-f89f-4eaa-90f1-3b34bf798ed5", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", - "service": "Azure Functions", - "severity": "高い", - "text": "App Service プランで実行されているすべての関数アプリで \"Always On\" が有効になっていることを確認する", - "waf": "確実" + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "6c19dfd5-a61c-436c-9001-491b9b3d0228", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#use-the-latest-ruleset-versions", + "service": "App Gateway", + "severity": "中程度", + "text": "最新の Azure Application Gateway WAF ルール セット バージョンを使用します。ルールセットの更新は、現在の脅威の状況を考慮して定期的に更新されます。", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "40a325c2-7c0e-49e6-86d8-c273b4dc21ba", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations?tabs=azure-cli#shared-storage-accounts", - "service": "Azure Functions", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "f84106a2-2e9e-42ac-add6-d3416ecfed53", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#add-diagnostic-settings-to-save-your-wafs-logs", + "service": "App Gateway", "severity": "中程度", - "text": "関数アプリを独自のストレージ アカウントにペアリングします。Function Apps のストレージ アカウントは、緊密に結合されていない限り、再利用しないようにしてください", - "waf": "確実" + "text": "診断設定を追加して、Azure Application Gateway WAF ログを保存します。", + "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "bb42650c-257d-4cb0-822a-131138b8e6f0", - "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", - "service": "Azure Functions", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "92664c60-47e3-4591-8b1b-8d557656e686", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#send-logs-to-microsoft-sentinel", + "service": "App Gateway", "severity": "中程度", - "text": "Azure DevOps または GitHub を活用して CI/CD を合理化し、関数アプリのコードを保護します", + "text": "Azure Application Gateway WAF ログを Microsoft Sentinel に送信します。", "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "ac1d6380-f866-4bbd-a9b4-b1ee5d7908b8", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#availability-zones", - "service": "IoT", - "severity": "高い", - "text": "Availability Zones (リージョンで適用可能な場合) を活用する (これは自動的に有効になります)", - "waf": "確実" + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "ba0e9b26-6e0d-4ec8-8541-023c00afd5b7", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#define-your-waf-configuration-as-code", + "service": "App Gateway", + "severity": "中程度", + "text": "Azure Application Gateway WAF 構成をコードとして定義します。コードを使用すると、新しいルール セット バージョンをより簡単に採用し、追加の保護を得ることができます。", + "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "35f651e8-0124-4ef7-8c57-658e38609e6e", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", - "service": "IoT", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "f17ec301-8470-4afd-aabc-c1fdfe47dcc0", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/policy-overview", + "service": "App Gateway", "severity": "中程度", - "text": "Microsoft が開始するフェールオーバーに注意してください。これらは、まれに、影響を受けるリージョンから対応する geo ペア リージョンにすべての IoT ハブをフェールオーバーするために Microsoft によって実行されます。", - "waf": "確実" + "text": "従来のWAF構成のかわりにWAFポリシーを使用します。", + "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "4ed3e490-dc06-4a1e-b467-5d0239d85540", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#cross-region-dr", - "service": "IoT", - "severity": "高い", - "text": "重要なワークロードに対するリージョン間 DR 戦略を検討する", - "waf": "確実" + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "d4eb8667-f8cb-4cdd-94e6-2f967ba98f88", + "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-secured-hub-app-gateway", + "service": "App Gateway", + "severity": "中程度", + "text": "バックエンドの受信トラフィックをフィルター処理して、Application Gateway サブネット (NSG など) からの接続のみを受け入れるようにします。", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "a11ecab0-db47-46f7-9aa7-17764e7e45a1", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", - "service": "IoT", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "a66f0fd8-2ca4-422e-8df3-235148127ca2", + "link": "https://learn.microsoft.com/azure/application-gateway/ssl-overview", + "service": "App Gateway", "severity": "高い", - "text": "手動フェールオーバーをトリガーする方法を学習します。", - "waf": "確実" + "text": "バックエンド サーバーへのトラフィックを暗号化する必要があります。", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "f9db8dfb-1194-460b-aedd-34dd6a69db22", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#failback", - "service": "IoT", + "arm-service": "microsoft.network/applicationGateways", + "checklist": "Azure Application Delivery Networking", + "guid": "3dba65cb-834d-44d8-a3ca-a6aa2f1587be", + "link": "https://learn.microsoft.com/azure/web-application-firewall/overview", + "service": "App Gateway", "severity": "高い", - "text": "フェールオーバー後にフェールバックする方法を学習します。", - "waf": "確実" + "text": "Web アプリケーション ファイアウォールを使用する必要があります。", + "waf": "安全" }, { "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant", - "guid": "553585a6-abe0-11ed-afa1-0242ac120002", - "link": "https://learn.microsoft.com/azure/application-gateway/overview-v2", + "guid": "0158fcb6-0bc1-4687-832f-cc7c359c22d2", + "link": "https://learn.microsoft.com/azure/application-gateway/redirect-overview", "service": "App Gateway", "severity": "中程度", - "text": "Application Gateway v2 SKU を使用していることを確認する", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "text": "HTTP を HTTPS にリダイレクトする", "waf": "安全" }, { - "arm-service": "Microsoft.Network/loadBalancers", + "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')", - "guid": "4e35fbf5-0ae2-48b2-97ce-753353edbd1a", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "service": "Load Balancer", + "guid": "bb697864-1b4c-43af-8667-90cc69aaed5f", + "link": "https://learn.microsoft.com/azure/application-gateway/how-application-gateway-works#modifications-to-the-request", + "service": "App Gateway", "severity": "中程度", - "text": "Azure Load Balancers に Standard SKU を使用していることを確認します", - "waf": "安全" + "text": "ゲートウェイで管理される Cookie を使用して、ユーザーセッションからのトラフィックを同じサーバーに転送して処理する", + "waf": "オペレーションズ" }, { - "arm-service": "Microsoft.Network/loadBalancers", + "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "guid": "9432621a-8397-4654-a882-5bc856b7ef83", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-standard-availability-zones", - "service": "Load Balancer", - "severity": "中程度", - "text": "Load Balancer フロントエンドの IP アドレスがゾーン冗長であることを確認します (ゾーン フロントエンドが必要な場合を除く)。", + "guid": "ff353ad8-15fb-4ae8-9fc5-a85a36d36a35", + "link": "https://learn.microsoft.com/azure/application-gateway/configuration-http-settings", + "service": "App Gateway", + "severity": "高い", + "text": "計画されたサービス更新中に接続ドレインを有効にして、バックエンド プールの既存のメンバーへの接続が失われないようにします", "waf": "安全" }, { "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant", - "guid": "dfc50f87-3800-424c-937b-ed5f186e7c15", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet", + "guid": "c8741f03-45a4-4183-a6b8-139e0773b8b5", + "link": "https://learn.microsoft.com/azure/application-gateway/custom-error", "service": "App Gateway", - "severity": "中程度", - "text": "Application Gateways v2 は、IP プレフィックスが /24 以上のサブネットにデプロイする必要があります", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "安全" + "severity": "低い", + "text": "カスタムエラーページを作成して、パーソナライズされたユーザーエクスペリエンスを表示する", + "waf": "オペレーションズ" }, { "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "description": "リバースプロキシの管理全般、特にWAFの管理は、ネットワーキングよりもアプリケーションに近いため、アプリと同じサブスクリプションに属します。Application Gateway と WAF を接続サブスクリプションに一元化することは、1 つのチームによって管理されている場合は問題ない可能性があります。", - "guid": "48b662d6-d15f-4512-a654-98f6dfe237de", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "guid": "f850d46f-f5d7-4b17-b48c-a780741402e1", + "link": "https://learn.microsoft.com/azure/application-gateway/rewrite-http-headers-url", "service": "App Gateway", "severity": "中程度", - "text": "ランディング ゾーン仮想ネットワーク内の受信 HTTP(S) 接続のプロキシに使用される Azure Application Gateway v2 またはパートナー NVA と、それらがセキュリティ保護しているアプリをデプロイします。", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "text": "HTTP 要求と応答ヘッダーを編集して、クライアントとサーバー間のルーティングと情報交換を容易にします", "waf": "安全" }, { "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "guid": "f109e1f3-c79b-4f14-82de-6b5c22314d08", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "guid": "eadc3164-4a0f-461c-85f1-1a372c04dfd1", + "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", "service": "App Gateway", "severity": "中程度", - "text": "アプリケーション ランディング ゾーン内のすべてのパブリック IP アドレスに対して、DDoS ネットワークまたは IP 保護プランを使用します。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "安全" + "text": "Front Door を構成して、グローバル Web トラフィックのルーティングと最上位のエンドユーザーのパフォーマンス、および迅速なグローバル フェイルオーバーによる信頼性を最適化する", + "waf": "パフォーマンス" }, { "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant", - "guid": "135bf4ac-f9db-461f-b76b-2ee9e30b12c0", - "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant", + "guid": "29dcc19f-a8fa-4c35-8281-290577538793", + "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", "service": "App Gateway", "severity": "中程度", - "text": "自動スケールは、最小インスタンス数が 2 になるように構成します。", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "確実" + "text": "トランスポート層の負荷分散を使用する", + "waf": "パフォーマンス" }, { "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant", - "guid": "060c6964-52b5-48db-af8b-83e4b2d85349", - "link": "https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2", + "guid": "276898c1-af5e-4819-9e8e-049c7801ab9d", + "link": "https://learn.microsoft.com/azure/application-gateway/multiple-site-overview", "service": "App Gateway", "severity": "中程度", - "text": "Application Gateway を複数の可用性ゾーンにデプロイする", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "確実" + "text": "1 つのゲートウェイ上の複数の Web アプリケーションのホスト名またはドメイン名に基づいてルーティングを構成する", + "waf": "安全" }, { - "arm-service": "microsoft.network/frontdoors", + "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "guid": "3f29812b-2363-4cef-b179-b599de0d5973", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "service": "Front Door", + "guid": "5fe365b6-58e8-47ed-a8cf-5163850380a2", + "link": "https://learn.microsoft.com/azure/application-gateway/create-ssl-portal", + "service": "App Gateway", "severity": "中程度", - "text": "Front Door と Application Gateway を使用して HTTP/S アプリを保護する場合は、Front Door で WAF ポリシーを使用します。Application Gateway をロックダウンして、Front Door からのトラフィックのみを受信します。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "text": "SSL証明書管理を一元化して、バックエンドサーバーファームからの暗号化と復号化のオーバーヘッドを削減します", "waf": "安全" }, { - "ammp": true, - "arm-service": "microsoft.network/trafficManagerProfiles", + "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Application Delivery Networking", - "guid": "cd4cd21b-0881-437f-9e6c-4cfd3e504547", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "service": "Traffic Manager", - "severity": "高い", - "text": "Traffic Manager を使用して、HTTP/S 以外のプロトコルにまたがるグローバル アプリを配信します。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "確実" - }, - { - "checklist": "Azure Application Delivery Networking", - "guid": "3b4b3e88-a459-4ed5-a22f-644dfbc58204", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "service": "Entra", + "guid": "fa64b4dd-35c2-4047-ac5c-45dfbf8b0db9", + "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-websocket", + "service": "App Gateway", "severity": "低い", - "text": "ユーザーが内部アプリケーションへのアクセスのみを必要とする場合、Microsoft Entra ID アプリケーション プロキシは Azure Virtual Desktop (AVD) の代替手段として検討されていますか?", - "training": "https://learn.microsoft.com/learn/modules/configure-azure-ad-application-proxy/", + "text": "Application Gateway を使用して WebSocket プロトコルと HTTP/2 プロトコルをネイティブにサポートする", "waf": "安全" }, { - "checklist": "Azure Application Delivery Networking", - "guid": "01ca7cf1-5754-442d-babb-8ba6772e5c30", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy#how-application-proxy-works", - "service": "Entra", - "severity": "中程度", - "text": "ネットワーク内の着信接続用に開かれるファイアウォール ポートの数を減らすには、Microsoft Entra ID アプリケーション プロキシを使用して、リモート ユーザーに内部アプリケーションへの安全で認証されたアクセスを提供することを検討してください。", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "32e42e36-11c8-418b-8a0b-c510e43a18a9", + "service": "AVS", + "severity": "高い", + "text": "ADDS ドメイン コントローラーがネイティブ Azure の ID サブスクリプションにデプロイされていることを確認する", "waf": "安全" }, { - "ammp": true, - "arm-service": "Microsoft.Network/loadBalancers", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant", - "guid": "97a2fd46-64b0-1dfa-b72d-9c8869496d75", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", - "service": "Load Balancer", - "severity": "高い", - "text": "Load Balancer のアウトバウンド規則の代わりに Azure NAT Gateway を使用して SNAT のスケーラビリティを向上させる", - "waf": "確実" + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "75089c20-990d-4927-b105-885576f76fc2", + "service": "AVS", + "severity": "中程度", + "text": "Azure ベースのリソース (Azure VMware Solution を含む) からの認証要求を Azure にローカルに保持するように ADDS サイトとサービスが構成されていることを確認します", + "waf": "安全" }, { - "ammp": true, - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "graph": "resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id", - "guid": "2f8e81eb-8e68-4026-8b1f-70f9b05f7cf9", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "de3aad1e-7c28-4ec9-9666-b7570449aa80", + "service": "AVS", "severity": "高い", - "text": "Azure Application Gateway WAF ボット保護ルール セットを有効にします。ボット ルールは、良いボットと悪いボットを検出します。", + "text": "vCenterがADDに接続されていることを確認し、「名前付きユーザーアカウント」に基づく認証を有効にします", "waf": "安全" }, { - "ammp": true, - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "8ea8e0d4-84e8-4b33-aeab-493f6391b4d6", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection", - "service": "App Gateway", - "severity": "高い", - "text": "Azure Application Gateway WAF ポリシーで要求本文の検査機能が有効になっているかどうかを確認します。", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "cd289ced-6b17-4db8-8554-61e2aee3553a", + "service": "AVS", + "severity": "中程度", + "text": "vCenter から ADDS への接続でセキュア プロトコル (LDAPS) が使用されていることを確認します", "waf": "安全" }, { - "ammp": true, - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "a4dd86d3-5ffa-408c-b660-cce073d085b8", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#tune-your-waf", - "service": "App Gateway", - "severity": "高い", - "text": "ワークロードの検出モードで Azure Application Gateway WAF を調整します。誤検出を減らします。", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "b9d37dac-43bc-46cd-8d79-a9b24604489a", + "service": "AVS", + "severity": "中程度", + "text": "vCenter IdP の CloudAdmin アカウントは、緊急アカウント(非常用アカウント)としてのみ使用されます", "waf": "安全" }, { - "ammp": true, - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "baf8e317-2397-4d49-b3d1-0dcc16d8778d", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/policy-overview?source=recommendations", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "53d88e89-d17b-473b-82a5-a67e7a9ed5b3", + "service": "AVS", "severity": "高い", - "text": "Application Gateway の WAF ポリシーを \"防止\" モードでデプロイします。", + "text": "NSX-Manager が外部 ID プロバイダ (LDAPS) と統合されていることを確認します。", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "43fae595-8a32-4299-a69e-0f32c454dcc9", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/rate-limiting-overview", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "ae0e37ce-e297-411b-b352-caaab79b198d", + "service": "AVS", "severity": "中程度", - "text": "Azure Application Gateway WAF にレート制限を追加します。レート制限は、クライアントが誤ってまたは意図的に短時間に大量のトラフィックを送信するのをブロックします。", + "text": "VMware vSphere 内で使用するために RBAC モデルが作成されているか", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "041e0ad8-7b12-4694-a0b7-a0e25ee2470f", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/rate-limiting-overview#rate-limiting-details", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "ab81932c-9fc9-4d1b-a780-36f5e6bfbb9e", + "service": "AVS", "severity": "中程度", - "text": "Azure Application Gateway WAF のレート制限には高いしきい値を使用します。レート制限のしきい値を高くすると、正当なトラフィックのブロックを回避しながら、インフラストラクチャを圧倒する可能性のある非常に多くのリクエストに対する保護を提供します。", + "text": "RBAC アクセス許可は、特定のユーザーではなく、ADDS グループに付与する必要があります", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "99937189-ff78-492a-b9ca-18d828d82b37", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#geo-filtering-best-practices", - "service": "App Gateway", - "severity": "低い", - "text": "すべての地理的地域からのトラフィックを想定していない場合は、geo フィルタを使用して、想定外の国からのトラフィックをブロックします。", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "d503547c-c447-4e82-9128-a71f0f1cac6d", + "service": "AVS", + "severity": "高い", + "text": "Azure の Azure VMware Solution リソースに対する RBAC アクセス許可は、限られた所有者のセットのみに \"ロックダウン\" されます", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "349a15c1-52f4-4319-9078-3895d95ecafd", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/geomatch-custom-rules", - "service": "App Gateway", - "severity": "中程度", - "text": "Azure Application Gateway WAF を使用してトラフィックを geo フィルタリングする場合は、不明な (ZZ) 場所を指定します。IP アドレスを地理的に一致できない場合に、正当な要求を誤ってブロックしないようにします。", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "fd9f0df4-68dc-4976-b9a9-e6a79f7682c5", + "service": "AVS", + "severity": "高い", + "text": "すべてのカスタム ロールのスコープが CloudAdmin で許可された承認で設定されていることを確認する", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "6c19dfd5-a61c-436c-9001-491b9b3d0228", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#use-the-latest-ruleset-versions", - "service": "App Gateway", - "severity": "中程度", - "text": "最新の Azure Application Gateway WAF ルール セット バージョンを使用します。ルールセットの更新は、現在の脅威の状況を考慮して定期的に更新されます。", - "waf": "安全" + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "9ef1d5e8-32e4-42e3-911c-818b0a0bc510", + "link": "https://github.com/Azure/AzureCAT-AVS/tree/main/networking", + "service": "AVS", + "severity": "高い", + "text": "お客様のユース ケースに適した Azure VMware Solution 接続モデルが選択されているか", + "waf": "パフォーマンス" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "f84106a2-2e9e-42ac-add6-d3416ecfed53", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#add-diagnostic-settings-to-save-your-wafs-logs", - "service": "App Gateway", - "severity": "中程度", - "text": "診断設定を追加して、Azure Application Gateway WAF ログを保存します。", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "eb710a37-cbc1-4055-8dd5-a936a8bb7cf5", + "service": "AVS", + "severity": "高い", + "text": "オンプレミスから Azure への ExpressRoute または VPN 接続が \"接続モニター\" を使用して監視されていることを確認する", "waf": "オペレーションズ" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "92664c60-47e3-4591-8b1b-8d557656e686", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#send-logs-to-microsoft-sentinel", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "976e24f2-a7f8-426c-9253-2a92a2a7ed99", + "service": "AVS", "severity": "中程度", - "text": "Azure Application Gateway WAF ログを Microsoft Sentinel に送信します。", + "text": "Azure VMware Solution バックエンドの ExpressRoute 接続を監視するために、Azure ネイティブ リソースから Azure VMware Solution 仮想マシンへの接続モニターが作成されていることを確認します", "waf": "オペレーションズ" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "ba0e9b26-6e0d-4ec8-8541-023c00afd5b7", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/best-practices#define-your-waf-configuration-as-code", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "f41ce6a0-64f3-4805-bc65-3ab50df01265", + "service": "AVS", "severity": "中程度", - "text": "Azure Application Gateway WAF 構成をコードとして定義します。コードを使用すると、新しいルール セット バージョンをより簡単に採用し、追加の保護を得ることができます。", + "text": "エンド 2 エンドの接続を監視するために、オンプレミス リソースから Azure VMware Solution 仮想マシンへの接続モニターが作成されていることを確認します", "waf": "オペレーションズ" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "f17ec301-8470-4afd-aabc-c1fdfe47dcc0", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/policy-overview", - "service": "App Gateway", - "severity": "中程度", - "text": "従来のWAF構成のかわりにWAFポリシーを使用します。", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "563b4dc7-4a74-48b6-933a-d1a0916a6649", + "service": "AVS", + "severity": "高い", + "text": "ルート サーバーを使用する場合は、ルート サーバーから ExR ゲートウェイ、オンプレミスに伝達されるルートが 1000 を超えないようにします (ARS 制限)。", "waf": "オペレーションズ" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "d4eb8667-f8cb-4cdd-94e6-2f967ba98f88", - "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-secured-hub-app-gateway", - "service": "App Gateway", - "severity": "中程度", - "text": "バックエンドの受信トラフィックをフィルター処理して、Application Gateway サブネット (NSG など) からの接続のみを受け入れるようにします。", - "waf": "安全" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "a66f0fd8-2ca4-422e-8df3-235148127ca2", - "link": "https://learn.microsoft.com/azure/application-gateway/ssl-overview", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "6128a71f-0f1c-4ac6-b9ef-1d5e832e42e3", + "service": "AVS", "severity": "高い", - "text": "バックエンド サーバーへのトラフィックを暗号化する必要があります。", + "text": "Azure Portal で Azure VMware Solution リソースを管理するロールに対して Privileged Identity Management が実装されていますか (永続的なアクセス許可は許可されません)", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "3dba65cb-834d-44d8-a3ca-a6aa2f1587be", - "link": "https://learn.microsoft.com/azure/web-application-firewall/overview", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "c4e2436b-b336-4d71-9f17-960eee0b9b5c", + "service": "AVS", "severity": "高い", - "text": "Web アプリケーション ファイアウォールを使用する必要があります。", + "text": "Privileged Identity Management 監査レポートは、Azure VMware Solution PIM ロールに対して実装する必要がある", "waf": "安全" }, { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "0158fcb6-0bc1-4687-832f-cc7c359c22d2", - "link": "https://learn.microsoft.com/azure/application-gateway/redirect-overview", - "service": "App Gateway", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "78c447a8-26b2-4863-af0f-1cac599ef1d5", + "service": "AVS", "severity": "中程度", - "text": "HTTP を HTTPS にリダイレクトする", - "waf": "安全" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "bb697864-1b4c-43af-8667-90cc69aaed5f", - "link": "https://learn.microsoft.com/azure/application-gateway/how-application-gateway-works#modifications-to-the-request", - "service": "App Gateway", - "severity": "中程度", - "text": "ゲートウェイで管理される Cookie を使用して、ユーザーセッションからのトラフィックを同じサーバーに転送して処理する", - "waf": "オペレーションズ" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "ff353ad8-15fb-4ae8-9fc5-a85a36d36a35", - "link": "https://learn.microsoft.com/azure/application-gateway/configuration-http-settings", - "service": "App Gateway", - "severity": "高い", - "text": "計画されたサービス更新中に接続ドレインを有効にして、バックエンド プールの既存のメンバーへの接続が失われないようにします", - "waf": "安全" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "c8741f03-45a4-4183-a6b8-139e0773b8b5", - "link": "https://learn.microsoft.com/azure/application-gateway/custom-error", - "service": "App Gateway", - "severity": "低い", - "text": "カスタムエラーページを作成して、パーソナライズされたユーザーエクスペリエンスを表示する", - "waf": "オペレーションズ" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "f850d46f-f5d7-4b17-b48c-a780741402e1", - "link": "https://learn.microsoft.com/azure/application-gateway/rewrite-http-headers-url", - "service": "App Gateway", - "severity": "中程度", - "text": "HTTP 要求と応答ヘッダーを編集して、クライアントとサーバー間のルーティングと情報交換を容易にします", - "waf": "安全" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "eadc3164-4a0f-461c-85f1-1a372c04dfd1", - "link": "https://learn.microsoft.com/azure/frontdoor/front-door-overview", - "service": "App Gateway", - "severity": "中程度", - "text": "Front Door を構成して、グローバル Web トラフィックのルーティングと最上位のエンドユーザーのパフォーマンス、および迅速なグローバル フェイルオーバーによる信頼性を最適化する", - "waf": "パフォーマンス" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "29dcc19f-a8fa-4c35-8281-290577538793", - "link": "https://learn.microsoft.com/azure/load-balancer/load-balancer-overview", - "service": "App Gateway", - "severity": "中程度", - "text": "トランスポート層の負荷分散を使用する", - "waf": "パフォーマンス" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "276898c1-af5e-4819-9e8e-049c7801ab9d", - "link": "https://learn.microsoft.com/azure/application-gateway/multiple-site-overview", - "service": "App Gateway", - "severity": "中程度", - "text": "1 つのゲートウェイ上の複数の Web アプリケーションのホスト名またはドメイン名に基づいてルーティングを構成する", - "waf": "安全" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "5fe365b6-58e8-47ed-a8cf-5163850380a2", - "link": "https://learn.microsoft.com/azure/application-gateway/create-ssl-portal", - "service": "App Gateway", - "severity": "中程度", - "text": "SSL証明書管理を一元化して、バックエンドサーバーファームからの暗号化と復号化のオーバーヘッドを削減します", - "waf": "安全" - }, - { - "arm-service": "microsoft.network/applicationGateways", - "checklist": "Azure Application Delivery Networking", - "guid": "fa64b4dd-35c2-4047-ac5c-45dfbf8b0db9", - "link": "https://learn.microsoft.com/azure/application-gateway/application-gateway-websocket", - "service": "App Gateway", - "severity": "低い", - "text": "Application Gateway を使用して WebSocket プロトコルと HTTP/2 プロトコルをネイティブにサポートする", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "32e42e36-11c8-418b-8a0b-c510e43a18a9", - "service": "AVS", - "severity": "高い", - "text": "ADDS ドメイン コントローラーがネイティブ Azure の ID サブスクリプションにデプロイされていることを確認する", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "75089c20-990d-4927-b105-885576f76fc2", - "service": "AVS", - "severity": "中程度", - "text": "Azure ベースのリソース (Azure VMware Solution を含む) からの認証要求を Azure にローカルに保持するように ADDS サイトとサービスが構成されていることを確認します", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "de3aad1e-7c28-4ec9-9666-b7570449aa80", - "service": "AVS", - "severity": "高い", - "text": "vCenterがADDに接続されていることを確認し、「名前付きユーザーアカウント」に基づく認証を有効にします", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "cd289ced-6b17-4db8-8554-61e2aee3553a", - "service": "AVS", - "severity": "中程度", - "text": "vCenter から ADDS への接続でセキュア プロトコル (LDAPS) が使用されていることを確認します", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "b9d37dac-43bc-46cd-8d79-a9b24604489a", - "service": "AVS", - "severity": "中程度", - "text": "vCenter IdP の CloudAdmin アカウントは、緊急アカウント(非常用アカウント)としてのみ使用されます", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "53d88e89-d17b-473b-82a5-a67e7a9ed5b3", - "service": "AVS", - "severity": "高い", - "text": "NSX-Manager が外部 ID プロバイダ (LDAPS) と統合されていることを確認します。", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "ae0e37ce-e297-411b-b352-caaab79b198d", - "service": "AVS", - "severity": "中程度", - "text": "VMware vSphere 内で使用するために RBAC モデルが作成されているか", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "ab81932c-9fc9-4d1b-a780-36f5e6bfbb9e", - "service": "AVS", - "severity": "中程度", - "text": "RBAC アクセス許可は、特定のユーザーではなく、ADDS グループに付与する必要があります", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "d503547c-c447-4e82-9128-a71f0f1cac6d", - "service": "AVS", - "severity": "高い", - "text": "Azure の Azure VMware Solution リソースに対する RBAC アクセス許可は、限られた所有者のセットのみに \"ロックダウン\" されます", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "fd9f0df4-68dc-4976-b9a9-e6a79f7682c5", - "service": "AVS", - "severity": "高い", - "text": "すべてのカスタム ロールのスコープが CloudAdmin で許可された承認で設定されていることを確認する", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "9ef1d5e8-32e4-42e3-911c-818b0a0bc510", - "link": "https://github.com/Azure/AzureCAT-AVS/tree/main/networking", - "service": "AVS", - "severity": "高い", - "text": "お客様のユース ケースに適した Azure VMware Solution 接続モデルが選択されているか", - "waf": "パフォーマンス" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "eb710a37-cbc1-4055-8dd5-a936a8bb7cf5", - "service": "AVS", - "severity": "高い", - "text": "オンプレミスから Azure への ExpressRoute または VPN 接続が \"接続モニター\" を使用して監視されていることを確認する", - "waf": "オペレーションズ" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "976e24f2-a7f8-426c-9253-2a92a2a7ed99", - "service": "AVS", - "severity": "中程度", - "text": "Azure VMware Solution バックエンドの ExpressRoute 接続を監視するために、Azure ネイティブ リソースから Azure VMware Solution 仮想マシンへの接続モニターが作成されていることを確認します", - "waf": "オペレーションズ" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "f41ce6a0-64f3-4805-bc65-3ab50df01265", - "service": "AVS", - "severity": "中程度", - "text": "エンド 2 エンドの接続を監視するために、オンプレミス リソースから Azure VMware Solution 仮想マシンへの接続モニターが作成されていることを確認します", - "waf": "オペレーションズ" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "563b4dc7-4a74-48b6-933a-d1a0916a6649", - "service": "AVS", - "severity": "高い", - "text": "ルート サーバーを使用する場合は、ルート サーバーから ExR ゲートウェイ、オンプレミスに伝達されるルートが 1000 を超えないようにします (ARS 制限)。", - "waf": "オペレーションズ" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "6128a71f-0f1c-4ac6-b9ef-1d5e832e42e3", - "service": "AVS", - "severity": "高い", - "text": "Azure Portal で Azure VMware Solution リソースを管理するロールに対して Privileged Identity Management が実装されていますか (永続的なアクセス許可は許可されません)", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "c4e2436b-b336-4d71-9f17-960eee0b9b5c", - "service": "AVS", - "severity": "高い", - "text": "Privileged Identity Management 監査レポートは、Azure VMware Solution PIM ロールに対して実装する必要がある", - "waf": "安全" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "78c447a8-26b2-4863-af0f-1cac599ef1d5", - "service": "AVS", - "severity": "中程度", - "text": "Privileged Identity Management を使用している場合は、Azure VMware Solution のホストの自動置換通知用の有効な SMTP レコードを使用して、有効な Entra ID が有効なアカウントが作成されていることを確認します。(常任許可が必要)", + "text": "Privileged Identity Management を使用している場合は、Azure VMware Solution のホストの自動置換通知用の有効な SMTP レコードを使用して、有効な Entra ID が有効なアカウントが作成されていることを確認します。(常任許可が必要)", "waf": "安全" }, { @@ -5647,94 +5279,422 @@ "waf": "確実" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "高い", - "text": "Azure Cache for Redis のゾーン冗長を有効にします。Azure Cache for Redis では、Premium レベルと Enterprise レベルでゾーン冗長構成がサポートされています。ゾーン冗長キャッシュでは、同じリージョン内の異なる Azure Availability Zones にノードを配置できます。これにより、データセンターや AZ の停止が単一障害点として排除され、キャッシュの全体的な可用性が向上します。", + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "3b7a56de-5020-4642-b3cb-c976e80b6d6d", + "link": "https://learn.microsoft.com/azure/logic-apps/single-tenant-overview-compare", + "service": "Logic Apps", + "severity": "高い", + "text": "ビジネスと SLO の要件に基づいて適切なロジック アプリのホスティング プランを選択する", "waf": "確実" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "3d7008bd-6bc1-4b03-8aa8-ec2a3b55786a", + "link": "https://learn.microsoft.com/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", + "service": "Logic Apps", + "severity": "高い", + "text": "ゾーンの冗長性と可用性ゾーンを使用してリージョンの障害からロジック アプリを保護する", + "waf": "確実" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "1cda768f-a206-445d-8234-56f6a6e7286e", + "link": "https://learn.microsoft.com/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", + "service": "Logic Apps", + "severity": "高い", + "text": "重要なワークロードに対するリージョン間 DR 戦略を検討する", + "waf": "確実" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "82118ec5-ed6f-4c68-9471-eb0da98a1b34", + "link": "https://learn.microsoft.com/azure/app-service/environment/intro", + "service": "Logic Apps", + "severity": "高い", + "text": "分離環境にデプロイする場合は、App Service Environment (ASE) v3 を使用するか、それらに移行します", + "waf": "確実" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "74275fa5-9e08-4c7e-b096-13b538fe1501", + "link": "https://learn.microsoft.com/training/modules/deploy-azure-functions/", + "service": "Logic Apps", + "severity": "中程度", + "text": "Azure DevOps または GitHub を活用して CI/CD を合理化し、ロジック アプリ コードを保護", + "waf": "オペレーションズ" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ストレージに関連する Microsoft クラウド セキュリティ ベンチマークのガイダンスを適用する", + "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", + "service": "Azure Storage", + "severity": "中程度", + "text": "\"ストレージの Azure セキュリティ ベースライン\" を検討する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "既定では、Azure Storage にはパブリック IP アドレスがあり、インターネットにアクセス可能です。プライベート エンドポイントを使用すると、アクセスが必要な Azure コンピューティング リソースにのみ Azure Storage を安全に公開できるため、パブリック インターネットへの露出を排除できます", + "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", + "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", + "service": "Azure Storage", + "severity": "高い", + "text": "Azure Storage にプライベート エンドポイントを使用することを検討する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "新しく作成されたストレージ アカウントは、RBAC や監査などがすべて有効になるように、ARM デプロイ モデルを使用して作成されます。サブスクリプションにクラシック デプロイ モデルの古いストレージ アカウントがないことを確認する", + "guid": "30e37c3e-2971-41b2-963c-eee079b598de", + "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", + "service": "Azure Storage", + "severity": "中程度", + "text": "古いストレージ アカウントで \"クラシック デプロイ モデル\" が使用されていないことを確認する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Microsoft Defender を活用して、不審なアクティビティや構成ミスについて学習します。", + "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", + "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", + "service": "Azure Storage", + "severity": "高い", + "text": "すべてのストレージ アカウントに対して Microsoft Defender を有効にする", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "論理的な削除メカニズムを使用すると、誤って削除された BLOB を回復できます。", + "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", + "service": "Azure Storage", + "severity": "中程度", + "text": "BLOB の \"論理的な削除\" を有効にする", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "たとえば、機密性、プライバシー、コンプライアンス上の理由などから、削除された情報がすぐに削除されるようにアプリケーションで確認する必要がある場合など、特定の BLOB コンテナーに対して \"論理的な削除\" を選択的に無効にすることを検討してください。", + "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "service": "Azure Storage", + "severity": "中程度", + "text": "BLOB の '論理的な削除' を無効にする", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "コンテナーの論理的な削除を使用すると、コンテナーが削除された後に回復できます (たとえば、偶発的な削除操作から回復します)。", + "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", + "service": "Azure Storage", + "severity": "高い", + "text": "コンテナーの \"論理的な削除\" を有効にする", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "たとえば、機密性、プライバシー、コンプライアンス上の理由などから、削除された情報がすぐに削除されるようにアプリケーションで確認する必要がある場合など、特定の BLOB コンテナーに対して \"論理的な削除\" を選択的に無効にすることを検討してください。", + "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "service": "Azure Storage", + "severity": "中程度", + "text": "コンテナーの \"論理的な削除\" を無効にする", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "削除前に削除ロックを最初に解除するようにユーザーに強制することで、ストレージ アカウントが誤って削除されないようにします", + "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "service": "Azure Storage", + "severity": "高い", + "text": "ストレージ アカウントでのリソース ロックの有効化", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "BLOB の \"訴訟ホールド\" または \"時間ベースの保持\" ポリシーを検討して、BLOB、コンテナー、またはストレージ アカウントを削除できないようにします。「不可能」は実際には「不可能」を意味することに注意してください。ストレージ アカウントに不変の BLOB が含まれる場合、そのストレージ アカウントを \"取り除く\" 唯一の方法は、Azure サブスクリプションを取り消すことです。", + "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", + "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", + "service": "Azure Storage", + "severity": "高い", + "text": "不変の BLOB を検討する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ストレージ アカウントへの保護されていない HTTP/80 アクセスを無効にして、すべてのデータ転送が暗号化され、整合性が保護され、サーバーが認証されるようにすることを検討してください。", + "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Azure Storage", + "severity": "高い", + "text": "HTTPS を要求する (つまり、ストレージ アカウントのポート 80 を無効にする)", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ストレージ アカウントでカスタム ドメイン (ホスト名) を構成する場合は、TLS/HTTPS が必要かどうかを確認します。その場合は、ストレージ アカウントの前に Azure CDN を配置する必要があります。", + "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", + "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", + "service": "Azure Storage", + "severity": "高い", + "text": "HTTPS を適用する (HTTP を無効にする) 場合は、ストレージ アカウントにカスタム ドメイン (CNAME) を使用していないことを確認します。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "クライアントが SAS トークンを使用して BLOB データにアクセスするときに HTTPS を要求すると、資格情報が失われるリスクを最小限に抑えることができます。", + "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", + "service": "Azure Storage", + "severity": "中程度", + "text": "Shared Access Signature (SAS) トークンを HTTPS 接続のみに制限する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "AAD トークンは、可能な限り、共有アクセス署名よりも優先する必要があります", + "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", + "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", + "service": "Azure Storage", + "severity": "高い", + "text": "BLOB アクセスに Azure Active Directory (Azure AD) トークンを使用する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ユーザー、グループ、またはアプリケーションにロールを割り当てる場合は、タスクの実行に必要なアクセス許可のみをセキュリティ プリンシパルに付与します。リソースへのアクセスを制限することで、意図しないデータの誤用と悪意のあるデータの誤用の両方を防ぐことができます。", + "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", + "service": "Azure Storage", + "severity": "中程度", + "text": "IaM アクセス許可の最小特権", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ユーザー委任 SAS は、Azure Active Directory (Azure AD) 資格情報と、SAS に指定されたアクセス許可によってセキュリティで保護されます。ユーザー委任 SAS は、そのスコープと機能の点でサービス SAS に似ていますが、サービス SAS よりもセキュリティ上の利点があります。", + "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", + "service": "Azure Storage", + "severity": "高い", + "text": "SAS を使用する場合は、ストレージ アカウント キー ベースの SAS よりも \"ユーザー委任 SAS\" を優先します。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ストレージ アカウント キー (\"共有キー\") には、監査機能がほとんどありません。誰がいつキーのコピーを取得したかを監視できますが、キーが複数の人の手に渡ると、使用状況を特定のユーザーに帰属させることは不可能です。AAD 認証のみに依存することで、ストレージへのアクセスをユーザーに結び付けやすくなります。", + "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", + "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", + "service": "Azure Storage", + "severity": "高い", + "text": "ストレージ アカウント キーを無効にして、AAD アクセス (およびユーザー委任 SAS) のみがサポートされるようにすることを検討してください。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "アクティビティ ログ データを使用して、ストレージ アカウントのセキュリティ (ストレージ アカウント キー、アクセス ポリシーなど) が \"いつ、誰が、何を、\"どのように\" 表示または変更されているかを特定します。", + "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", + "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", + "service": "Azure Storage", + "severity": "高い", + "text": "Azure Monitor を使用して、ストレージ アカウントに対するコントロール プレーン操作を監査することを検討してください", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "キーの有効期限ポリシーを使用すると、アカウントアクセスキーのローテーションのリマインダーを設定できます。リマインダーは、指定した間隔が経過し、キーがまだローテーションされていない場合に表示されます。", + "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", + "service": "Azure Storage", + "severity": "中程度", + "text": "ストレージ アカウント キーを使用する場合は、\"キーの有効期限ポリシー\" を有効にすることを検討してください", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS 有効期限ポリシーでは、SAS が有効である推奨間隔を指定します。SAS 有効期限ポリシーは、サービス SAS またはアカウント SAS に適用されます。ユーザーがサービス SAS またはアカウント SAS を、推奨間隔よりも長い有効期間で生成すると、警告が表示されます。", + "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", + "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", + "service": "Azure Storage", + "severity": "中程度", + "text": "SAS 有効期限ポリシーの構成を検討する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "保存されているアクセス ポリシーを使用すると、ストレージ アカウント キーを再生成することなく、サービス SAS のアクセス許可を取り消すことができます。", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", + "service": "Azure Storage", + "severity": "中程度", + "text": "保存されているアクセス ポリシーに SAS をリンクすることを検討する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", + "service": "Azure Storage", + "severity": "中程度", + "text": "チェックインされた接続文字列とストレージ アカウント キーを検出するようにアプリケーションのソース コード リポジトリを構成することを検討してください。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "理想的には、アプリケーションでマネージド ID を使用して Azure Storage に対する認証を行う必要があります。それが不可能な場合は、ストレージ資格情報 (接続文字列、ストレージ アカウント キー、SAS、サービス プリンシパル資格情報) を Azure KeyVault または同等のサービスに用意することを検討してください。", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", + "service": "Azure Storage", + "severity": "高い", + "text": "接続文字列を Azure KeyVault に格納することを検討する (マネージド ID が不可能なシナリオの場合)", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "アドホック SAS サービス SAS またはアカウント SAS で、有効期限が近づいています。このように、SAS が侵害された場合でも、有効期間は短時間です。この方法は、保存されているアクセス ポリシーを参照できない場合に特に重要です。また、有効期限が近いと、BLOB にアップロードできる時間が制限されるため、BLOB に書き込めるデータの量も制限されます。", + "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", + "severity": "高い", + "text": "アドホックSASの有効期間を短くする", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS を作成するときは、できるだけ具体的かつ制限的にしてください。1 つのリソースと操作には、より広範なアクセスを提供する SAS よりも SAS を優先します。", + "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", "severity": "中程度", - "text": "Azure Cache for Redis インスタンスのデータ永続化を構成します。キャッシュ データはメモリに格納されるため、まれに複数のノードで計画外の障害が発生すると、すべてのデータがドロップされる可能性があります。データの完全な損失を回避するために、Redis 永続化では、メモリ内データのスナップショットを定期的に取得し、ストレージ アカウントに格納できます。", - "waf": "確実" + "text": "SAS に狭いスコープを適用する", + "waf": "安全" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS には、SAS を使用してリソースを要求する権限をクライアント IP アドレスまたはアドレス範囲に与えるパラメーターを含めることができます。", + "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", + "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", + "service": "Azure Storage", "severity": "中程度", - "text": "geo 冗長ストレージ アカウントを使用して Azure Cache for Redis データを保持するか、geo 冗長性を使用できない場合はゾーン冗長を使用します", - "waf": "確実" + "text": "可能な限り、SAS のスコープを特定のクライアント IP アドレスに設定することを検討してください", + "waf": "安全" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", - "severity": "中程度", - "text": "Premium Azure Cache for Redis インスタンスのパッシブ geo レプリケーションを構成します。geo レプリケーションは、2 つ以上の Azure Cache for Redis インスタンス (通常は 2 つの Azure リージョンにまたがる) をリンクするためのメカニズムです。geo レプリケーションは、主にリージョン間のディザスター リカバリー用に設計されています。2 つの Premium レベルのキャッシュ インスタンスは、プライマリ キャッシュへの読み取りと書き込みを提供する方法で geo レプリケーションを介して接続され、そのデータはセカンダリ キャッシュにレプリケートされます。", - "waf": "確実" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS は、クライアントがアップロードするデータの量を制限できません。時間の経過に伴うストレージ容量の価格モデルを考えると、クライアントが悪意を持って大きなコンテンツをアップロードしたかどうかを検証することは理にかなっているかもしれません。", + "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", + "service": "Azure Storage", + "severity": "低い", + "text": "クライアントが SAS を使用してファイルをアップロードした後、アップロードされたデータを確認することを検討してください。", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "3b7a56de-5020-4642-b3cb-c976e80b6d6d", - "link": "https://learn.microsoft.com/azure/logic-apps/single-tenant-overview-compare", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "\"ローカル ユーザー アカウント\" を使用して SFTP 経由で BLOB ストレージにアクセスする場合、\"通常の\" RBAC 制御は適用されません。NFS または REST 経由の BLOB アクセスは、SFTP アクセスよりも制限が厳しい場合があります。残念ながら、2023 年初頭の時点で、SFTP エンドポイントで現在サポートされている ID 管理の形式はローカル ユーザーだけです", + "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", + "service": "Azure Storage", "severity": "高い", - "text": "ビジネスと SLO の要件に基づいて適切なロジック アプリのホスティング プランを選択する", - "waf": "確実" + "text": "SFTP: SFTPアクセスの「ローカルユーザー」の数を制限し、時間の経過とともにアクセスが必要かどうかを監査します。", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "3d7008bd-6bc1-4b03-8aa8-ec2a3b55786a", - "link": "https://learn.microsoft.com/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", - "service": "Logic Apps", - "severity": "高い", - "text": "ゾーンの冗長性と可用性ゾーンを使用してリージョンの障害からロジック アプリを保護する", - "waf": "確実" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", + "service": "Azure Storage", + "severity": "中程度", + "text": "SFTP: SFTP エンドポイントは、POSIX ライクな ACL をサポートしていません。", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "1cda768f-a206-445d-8234-56f6a6e7286e", - "link": "https://learn.microsoft.com/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "ストレージは、CORS (Cross-Origin Resource Sharing)、つまり、異なるドメインの Web アプリが同一生成元ポリシーを緩めることを可能にする HTTP 機能をサポートしています。CORS を有効にする場合は、CorsRules を最小の特権に保ちます。", + "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", + "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", + "service": "Azure Storage", "severity": "高い", - "text": "重要なワークロードに対するリージョン間 DR 戦略を検討する", - "waf": "確実" + "text": "過度に広範な CORS ポリシーを避ける", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "82118ec5-ed6f-4c68-9471-eb0da98a1b34", - "link": "https://learn.microsoft.com/azure/app-service/environment/intro", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "保存データは常にサーバー側で暗号化され、さらにクライアント側でも暗号化される場合があります。サーバー側の暗号化は、プラットフォーム マネージド キー (既定) またはカスタマー マネージド キーを使用して行われる場合があります。クライアント側の暗号化は、クライアントが BLOB ごとに暗号化/暗号化解除キーを Azure Storage に提供するか、クライアント側で暗号化を完全に処理することによって行われます。そのため、機密性の保証を Azure Storage にまったく依存しません。", + "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", + "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", + "service": "Azure Storage", "severity": "高い", - "text": "分離環境にデプロイする場合は、App Service Environment (ASE) v3 を使用するか、それらに移行します", - "waf": "確実" + "text": "保存データの暗号化方法を決定します。データのスレッド モデルを理解します。", + "waf": "安全" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "74275fa5-9e08-4c7e-b096-13b538fe1501", - "link": "https://learn.microsoft.com/training/modules/deploy-azure-functions/", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", + "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", + "service": "Azure Storage", "severity": "中程度", - "text": "Azure DevOps または GitHub を活用して CI/CD を合理化し、ロジック アプリ コードを保護", - "waf": "オペレーションズ" + "text": "どのプラットフォーム暗号化を使用するか、または使用するかを決定します。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", + "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "service": "Azure Storage", + "severity": "中程度", + "text": "クライアント側の暗号化を使用するかどうかを決定します。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Resource Graph エクスプローラー (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) を利用して、匿名 BLOB アクセスを許可するストレージ アカウントを検索します。", + "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", + "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", + "service": "Azure Storage", + "severity": "高い", + "text": "パブリック BLOB アクセスが必要かどうか、または特定のストレージ アカウントに対して無効にできるかどうかを検討します。", + "waf": "安全" }, { "arm-service": "Microsoft.Devices/provisioningServices", @@ -5786,6 +5746,208 @@ "text": "Azure DevOps または GitHub を活用して CI/CD を合理化し、ロジック アプリ コードを保護", "waf": "オペレーションズ" }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "データの流出を防ぐために、画像のエクスポートを無効にします。これにより、別の ACR インスタンスに画像がインポートされなくなることに注意してください。", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "高い", + "text": "Azure Container Registry イメージのエクスポートを無効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry の Azure Policy を有効にすることで、監査コンプライアンスの可視性を有効にする", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "高い", + "text": "Azure Container Registry の Azure ポリシーを有効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Key Vault (AKV) は、AKV プラグイン (azure-kv) という表記を使用して、コンテナー イメージやその他の成果物に署名および検証できる署名キーを格納するために使用されます。Azure Container Registry (ACR) では、これらの署名を az?or?oras?CLI コマンド。", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "高い", + "text": "表記法によるコンテナの署名と検証(Notary v2)", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry は、格納するイメージやその他の成果物を自動的に暗号化します。既定では、Azure はサービス マネージド キーを使用して、保存中のレジストリ コンテンツを自動的に暗号化します。カスタマー管理のキーを使用すると、デフォルトの暗号化を追加の暗号化レイヤーで補完できます。", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "中程度", + "text": "カスタマー マネージド キーを使用してレジストリを暗号化する", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "マネージド ID を使用して、クライアント アプリケーションからの ACRPull/Push RBAC アクセスをセキュリティで保護する", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "高い", + "text": "サービス プリンシパルの代わりにマネージド ID を使用して接続する", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "ローカルの管理者アカウントはデフォルトで無効になっているため、有効にしないでください。代わりに、トークンまたは RBAC ベースのアクセス方法を使用してください", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "高い", + "text": "管理プレーン アクセスのローカル認証を無効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "管理者アカウントを無効にし、ACR プル/プッシュ操作のプリンシパルに RBAC ロールを割り当てる", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "高い", + "text": "ID プリンシパルに管理アクセス権を付与するのではなく、AcrPull および AcrPush RBAC ロールを割り当てる", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "匿名プル/プッシュ アクセスを無効にする", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "中程度", + "text": "匿名プル アクセスを無効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "トークン認証では、AAD プリンシパルへの割り当てはサポートされていません。提供されたトークンは、トークンにアクセスできる人なら誰でも使用できます", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "高い", + "text": "リポジトリ スコープのアクセス トークンを無効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "信頼されたネットワーク内のプライベート エンドポイントの背後にある ACR にコンテナー イメージをデプロイする", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "高い", + "text": "信頼できる環境からのイメージのデプロイ", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "認証に使用できるのは、ACR 対象ユーザーを持つトークンのみです。ACR の条件付きアクセス ポリシーを有効にするときに使用されます", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "中程度", + "text": "認証のために Azure ARM 対象ユーザー トークンを無効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "'repositoryEvents' と 'LoginEvents' をログ記録と監視の中心的な宛先として Log Analytics に送信するように診断設定を設定します。これにより、ACR リソース自体のコントロール プレーン アクティビティを監視できます。", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "中程度", + "text": "診断ログを有効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "サービスでは、サービス レベルの IP ACL フィルタリング規則 (NSG や Azure Firewall ではない) を使用するか、\"パブリック ネットワーク アクセスを無効にする\" トグル スイッチを使用して、パブリック ネットワーク アクセスを無効にすることがサポートされています", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "中程度", + "text": "Private Link を使用して受信ネットワーク アクセスを制御する", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Private Link を使用して受信ネットワーク アクセスがセキュリティで保護されている場合は、パブリック ネットワーク アクセスを無効にする", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "中程度", + "text": "パブリックネットワークアクセスを無効にする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "ACR Premium SKU のみが Private Link アクセスをサポートします", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "中程度", + "text": "Private Link をサポートする Azure Container Registry SKU を使用する (Premium SKU)", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Defender for containers または同等のサービスを使用して、コンテナー イメージの脆弱性をスキャンする必要があります", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "低い", + "text": "Defender for Containers で Azure Container Registry の脆弱性をスキャンできるようにする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "DevSecOps のプラクティスに従って脆弱性が検証およびスキャンされた信頼できるコードをデプロイします。", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "severity": "中程度", + "text": "検証済みのコンテナイメージをデプロイする", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "サポートされているプラットフォーム、プログラミング言語、プロトコル、およびフレームワークの最新バージョンを使用してください。", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "高い", + "text": "最新のプラットフォーム、言語、プロトコル、フレームワークを使用", + "waf": "安全" + }, { "arm-service": "Microsoft.AppPlatform/Spring", "checklist": "Azure Spring Apps Review", @@ -8485,6 +8647,17 @@ "text": "Synapse 上の sql ワークロードでのローカル ユーザーの使用を制限する", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "これはデフォルトのデプロイメントで有効になっているため、追加の構成は必要ありません。", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "転送中の機密データを暗号化する", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8496,6 +8669,15 @@ "text": "マネージド ID を使用してサービスに対して認証する", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "デフォルトで保存データの暗号化を有効にする", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8506,6 +8688,17 @@ "text": "高い権限を持つユーザーや管理ユーザーを分離して制限し、MFAと条件付きポリシーを有効にする", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Keyvaults を使用して CMK を保存する", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "必要に応じて、保存データの暗号化でカスタマー マネージド キー オプションを使用する", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8538,6 +8731,16 @@ "text": "マネージド vnet ワークスペースを使用して、パブリック インターネット経由のアクセスを制限する", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "デフォルトの認証方法として Microsoft Entra ID を使用します。", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "severity": "高い", + "text": "Microsoft Entra ID を既定の認証方法として使用し、可能な限りローカル アクセスを無効にします", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8549,6 +8752,16 @@ "text": "外部サービスに接続し、パブリックアクセスを無効にするようにプライベートエンドポイントを設定します", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "デフォルトの認証方法として Microsoft Entra ID を使用します。", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "マネージド ID を使用してサービスに対して認証する", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8559,6 +8772,15 @@ "text": "パブリック アクセスを有効にする場合は、IP ファイアウォール ルールを構成することを強くお勧めします", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "条件付きアクセス ポリシーを構成して、データ プレーンでのアクセスを制限する", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8569,6 +8791,16 @@ "text": "企業ネットワークから離れるべきではない機密データを扱っている場合は、vnet に SHIR VM をデプロイします", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "キーと secert の公開を制限する", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "severity": "高い", + "text": "Azure Key Vault を使用して、シークレットと crendentials を格納します。", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8580,6 +8812,37 @@ "text": "データ流出防止 (DEP) を有効にする", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "severity": "高い", + "text": "高い権限を持つユーザーや管理ユーザーを分離して制限する", + "waf": "安全" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Event Hubs 名前空間を作成すると、名前空間に対して RootManageSharedAccessKey という名前のポリシー ルールが自動的に作成されます。このポリシーには、名前空間全体に対する管理アクセス許可があります。このルールは管理ルート アカウントのように扱い、アプリケーションで使用しないことをお勧めします。ポータルの名前空間の [構成] タブで、PowerShell または Azure CLI を使用して追加のポリシー ルールを作成できます。ローカル認証方法やアカウントの使用は避け、可能な限り無効にする必要があります。代わりに、可能な場合は Azure AD を使用して認証します。", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "Shared Access Signature (SAS) を使用して Event Hubs リソースへのアクセスを認証し、ローカル ユーザーを制限する", + "waf": "安全" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure ロールベースのアクセス制御 (Azure RBAC) を使用して、組み込みのロール割り当てを通じて Azure リソースへのアクセスを管理します。Azure RBAC ロールは、ユーザー、グループ、サービス プリンシパル、マネージド ID に割り当てることができます。", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "Azure RBAC を使用してアクセスをきめ細かくする", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8591,6 +8854,16 @@ "text": "ワークスペースのカスタマー マネージド キーを使用した保存時のデータ暗号化", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "サービスでは、サービス レベルの IP ACL フィルタリング規則 (NSG や Azure Firewall ではない) を使用するか、\"パブリック ネットワーク アクセスを無効にする\" トグル スイッチを使用して、パブリック ネットワーク アクセスを無効にすることがサポートされています。", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "パブリックネットワークアクセスの無効化", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8602,6 +8875,15 @@ "text": "転送中のデータ暗号化", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "Vnets を使用して、制限されたネットワーク上のトラフィックを分離する", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8612,6 +8894,111 @@ "text": "パスワード、セキュリティ、キーを Azure Key Vault に格納する", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "中程度", + "text": "Private Link 機能をサポートするすべての Azure リソースにプライベート エンドポイントをデプロイして、リソースのプライベート アクセス ポイントを確立します。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "資格情報またはシークレット値を Azure Key Vault に格納し、パイプラインの実行中にそれらを使用してアクティビティに渡すことができます。", + "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "中程度", + "text": "パイプライン アクティビティで Azure Key Vault シークレットを使用する", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric は、ワークスペースを使用してデータ アクセスを制御します。ワークスペースでは、データは Fabric アイテムの形式で表示され、ワークスペースへのアクセス権を付与しない限り、ユーザーはアイテム (データ) を表示または使用できません。ワークスペースとアイテムのアクセス許可の詳細については、「アクセス許可モデル」を参照してください。", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ワークスペース ロールを使用して、データに対するアクセス権をユーザーに付与します", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "OneLake RBAC は、ロールの割り当てを使用して、メンバーにアクセス許可を適用します。", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Onelake で RBAC を使用して、Onelake のテーブル/ファイル内のデータに対するきめ細かなアクセスを提供します", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "ショートカットのターゲットとソースの両方の場所でのユーザーのアクセスを考慮に入れます", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ショートカットを使用する場合、ユーザーのユーザー ID は、ショートカットのターゲットの場所にもアクセスできる必要があります", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "すべてのユーザーがロールを使用してワークスペース全体にアクセスする必要はないため、代わりにワークスペース全体でロールを付与することを制限し、アイテムの共有機能を使用するか、Fabric で権限を管理するユーザーのみにアイテムを共有します", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ワークスペース レベルのロールの提供をユーザーに制限し、代わりにアイテムをユーザーのみに共有します", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "RLS、CLS、ダイナミック データ マスキングなどの機能を使用して、SQL ワークロードのデータ セキュリティ要件を強化します。", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Warehouse と SQL 分析エンドポイントで RLS、CLS、動的データ マスキングを定義することで、データへのアクセスを制限します", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Power BI で RLS や OLS などの機能を使用して、セマンティック モデルでより多くのセキュリティ機能を使用", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Power BI のセマンティック モデルで RLS と OLS を定義して、データへのアクセスを制限する", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric では、OneLake に格納されているすべてのデータは保存時に暗号化されます", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "保存データの暗号化", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Microsoft サービス間でパブリック インターネット経由で転送されるデータは、常に少なくとも TLS 1.2 で暗号化されます。Fabric は、可能な限り TLS 1.3 にネゴシエートします。", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "転送中のデータを暗号化する", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8622,6 +9009,16 @@ "text": "必要に応じてローカルユーザーの使用を制限する", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "何もする必要はありません。Fabric に接続するすべての要求は Microsoft Entra ID で認証されるため、ユーザーは会社のオフィスから、自宅での作業中、またはリモートの場所から Fabric に安全に接続できます。", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Microsoft Entra ID を既定の認証方法として使用する", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8633,6 +9030,16 @@ "text": "マネージド ID を使用してサービスに対して認証する", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric ワークスペース ID は、Fabric ワークスペースに関連付けることができる、自動的に管理されるサービス プリンシパルです。ワークスペース ID は、 [マイ ワークスペース] を除く任意のワークスペースのワークスペース設定で作成できます。ワークスペース ID には、ワークスペース共同作成者ロールが自動的に割り当てられ、ワークスペース項目にアクセスできます。 制限事項: 認証方法としてワークスペース ID を使用すると、ショートカットの宛先への書き込みが失敗します。workspace-identity-authentication を使用した接続は、Onelake ショートカットとデータ パイプラインでのみ使用できます。", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ワークスペース ID を使用してサービスに対して認証する", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8643,6 +9050,35 @@ "text": "高い権限を持つユーザーや管理ユーザーを分離して制限し、MFAと条件付きポリシーを有効にする", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "ストレージ アカウントに対する ID のアクセス許可を付与する", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ストレージ アカウントの RBAC ロールをマネージド ID に指定して、接続を成功させます", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "service": "Azure Data Factory", + "severity": "中程度", + "text": "パブリックインターネット経由のアクセスを無効にし、ファイアウォールルールまたは信頼できるサービスルールのいずれかを設定します", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "ワークスペース ID を持つファブリック ワークスペースは、OneLake ショートカットの信頼されたワークスペース アクセスを通じて、ファイアウォール対応の Azure Data Lake Storage Gen2 アカウントに対して安全に読み取りまたは書き込みを行うことができます。", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ファイアウォールの内側にあるストレージ アカウントにアクセスするための信頼されたワークスペース アクセスを構成する", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8652,6 +9088,17 @@ "text": "企業ネットワークから離れるべきではない機密データを扱っている場合は、vnet に SHIR VM をデプロイします", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "マネージド仮想ネットワークは、Microsoft Fabric によって各 Fabric ワークスペースに対して作成および管理される仮想ネットワークです。マネージド仮想ネットワークは、Fabric Spark ワークロードのネットワーク分離を提供するため、コンピューティング クラスターは専用ネットワークにデプロイされ、共有仮想ネットワークの一部ではなくなります。これは、Fabric の Spark ワークロードでのみサポートされます。", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ネットワーク分離が必要な場合は、managed vnet オプションを使用してください", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8662,6 +9109,17 @@ "text": "マネージド vnet IR を使用して、Azure Integration Runtime のパブリック インターネット経由のアクセスを制限する", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "マネージド プライベート エンドポイントは、Fabric Spark ワークロードからデータ ソースへの安全でプライベートなアクセスを可能にする機能です。スターター・プールは、管理対象 PE では使用できません", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Azure サービスにアクセスするためのマネージド プライベート エンドポイントの構成", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8673,6 +9131,82 @@ "text": "マネージド プライベート エンドポイントを構成して、マネージド Azure IR を使用してリソースに接続する", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric は、仮想ネットワークのプライベート IP アドレスを使用します。このエンドポイントにより、ネットワーク内のユーザーは、プライベートリンクを使用してプライベートIPアドレスを介してFabricと通信できます。", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Private Link を構成して、独自の Azure vnet 内のリソース (Fabric 環境に来るトラフィック) にアクセスします", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "ユーザーの認証を受けるタイミングは、IP アドレス、場所、管理対象デバイスなどの一連のポリシーに基づいて決定されます。", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "ユーザーが Fabric 環境にアクセスしようとしている場合に Microsoft Entra ID の条件付きアクセスを構成する", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure では、サービス タグは定義された IP アドレスのグループであり、ネットワーク セキュリティ規則の更新や変更の複雑さを最小限に抑えるために、グループとして自動的に管理されます。", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Azure サービス タグを使用して、Microsoft Fabric との間の接続を有効にすることができます。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "随意", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Fabric URL を許可リストに追加できます", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "随意", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "Power BI の URL を許可リストに追加できます", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "データ ゲートウェイを使用すると、Azure やその他のデータ サービスを Microsoft Fabric と Power Platform に接続して、データ ソースと安全に通信し、クエリを実行し、結果をサービスに送信できます。", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "中程度", + "text": "オンプレミス データ ゲートウェイまたは Vnet データ ゲートウェイを構成して使用し、オンプレミスまたは仮想ネットワークの背後にあるソースに接続する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure Private Link を使用すると、プライベート エンドポイントを介して Azure のさまざまなサービスとしてのプラットフォーム (PaaS) デプロイに接続できます。プライベート エンドポイントは、特定の仮想ネットワークとサブネット内のプライベート IP アドレスです", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", + "severity": "中程度", + "text": "顧客の Vnet とデータ ファクトリのソースに接続するように Private Link を構成する", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -8714,6 +9248,28 @@ "text": "パスワードとシークレットを Azure Key Vault に格納する", "waf": "安全" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "資格情報またはシークレット値を Azure Key Vault に格納し、パイプラインの実行中にそれらを使用してアクティビティに渡すことができます。", + "guid": "6f4a1652-bddd-4ea8-a487-cdec4861bc3b", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "中程度", + "text": "パイプライン アクティビティで Azure Key Vault シークレットを使用する", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "オンプレミスのデータ ストア (機密情報を含むリンクされたサービス) の資格情報を暗号化して、セルフホステッド統合ランタイムを備えたマシンに格納できます。", + "guid": "c14aeb7e-66e8-4d9a-9bec-218e6436b173", + "link": "https://learn.microsoft.com/azure/data-factory/encrypt-credentials-self-hosted-integration-runtime", + "service": "Azure Data Factory", + "severity": "中程度", + "text": "Azure Data Factory の SHIR データ ストアを使用してオンプレミスの資格情報を暗号化する", + "waf": "安全" + }, { "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "guid": "6db55f57-9603-4334-adf9-cc23418db612", @@ -8978,6 +9534,17 @@ "text": "クラスターの作成権限を制限します。", "waf": "安全" }, + { + "arm-service": "Microsoft.Databricks/workspaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "アカウント管理者は、RestrictWorkspaceAdmins というワークスペース設定を構成して、ワークスペース管理者がジョブ所有者を自分自身に変更し、ジョブ実行設定をサービス プリンシパル ユーザー ロールを持つサービス プリンシパルに変更するように制限できます。", + "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", + "severity": "高い", + "text": "ワークスペース管理者を制限する", + "waf": "安全" + }, { "arm-service": "Microsoft.Databricks/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -9468,6 +10035,46 @@ "text": "配信元を App Services として Front Door を使用する場合は、アクセス制限を使用して Azure Front Door 経由でのみアプリ サービスへのトラフィックをロックダウンすることを検討してください。", "waf": "安全" }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "高い", + "text": "Azure Cache for Redis のゾーン冗長を有効にします。Azure Cache for Redis では、Premium レベルと Enterprise レベルでのゾーン冗長構成がサポートされています。ゾーン冗長キャッシュは、同じリージョン内の異なる Azure Availability Zones にノードを配置できます。これにより、データセンターや AZ の障害点としての停止が排除され、キャッシュの全体的な可用性が向上します。", + "waf": "確実" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "中程度", + "text": "Azure Cache for Redis インスタンスのデータ永続化を構成します。キャッシュ データはメモリに格納されるため、まれに複数のノードで予期しない障害が発生すると、すべてのデータがドロップされる可能性があります。データが完全に失われないように、Redis 永続化では、メモリ内データのスナップショットを定期的に作成し、それをストレージ アカウントに格納できます。", + "waf": "確実" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "中程度", + "text": "Geo 冗長ストレージ アカウントを使用して Azure Cache for Redis データを保持するか、geo 冗長性を使用できない場合はゾーン冗長を使用します", + "waf": "確実" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "中程度", + "text": "Premium Azure Cache for Redis インスタンスのパッシブ geo レプリケーションを構成します。geo レプリケーションは、2 つ以上の Azure Cache for Redis インスタンス (通常は 2 つの Azure リージョンにまたがる) をリンクするためのメカニズムです。geo レプリケーションは、主にリージョン間のディザスター リカバリー用に設計されています。2 つの Premium レベルのキャッシュ インスタンスは、プライマリ キャッシュに対して読み取りと書き込みを提供する方法で geo レプリケーションを介して接続され、そのデータはセカンダリ キャッシュにレプリケートされます。", + "waf": "確実" + }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", @@ -10670,7 +11277,7 @@ ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/waf_checklist.ko.json b/checklists/waf_checklist.ko.json index 70ac0f31..c2d8a82c 100644 --- a/checklists/waf_checklist.ko.json +++ b/checklists/waf_checklist.ko.json @@ -1,45 +1,5 @@ { "items": [ - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "높다", - "text": "Azure Cache for Redis에 대한 영역 중복성을 사용하도록 설정합니다. Azure Cache for Redis는 프리미엄 및 엔터프라이즈 계층에서 영역 중복 구성을 지원합니다. 영역 중복 캐시는 동일한 지역의 여러 Azure 가용성 영역에 노드를 배치할 수 있습니다. 데이터 센터 또는 AZ 중단을 단일 장애 지점으로 제거하고 캐시의 전반적인 가용성을 높입니다.", - "waf": "신뢰도" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", - "severity": "보통", - "text": "Azure Cache for Redis 인스턴스에 대한 데이터 지속성을 구성합니다. 캐시 데이터는 메모리에 저장되기 때문에 드물게 계획되지 않은 여러 노드의 오류로 인해 모든 데이터가 삭제될 수 있습니다. 데이터가 완전히 손실되는 것을 방지하기 위해 Redis 지속성을 사용하면 메모리 내 데이터의 주기적인 스냅숏을 만들어 저장소 계정에 저장할 수 있습니다.", - "waf": "신뢰도" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", - "severity": "보통", - "text": "지역 중복 스토리지 계정을 사용하여 Azure Cache for Redis 데이터를 유지하거나 지역 중복을 사용할 수 없는 경우 영역 중복을 유지합니다", - "waf": "신뢰도" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", - "severity": "보통", - "text": "프리미엄 Azure Cache for Redis 인스턴스에 대한 수동 지역 복제를 구성합니다. 지역에서 복제는 일반적으로 두 개의 Azure 지역에 걸쳐 있는 둘 이상의 Azure Cache for Redis 인스턴스를 연결하는 메커니즘입니다. 지역에서 복제는 주로 지역 간 재해 복구를 위해 설계되었습니다. 두 개의 프리미엄 계층 캐시 인스턴스는 주 캐시에 대한 읽기 및 쓰기를 제공하는 방식으로 지역 복제를 통해 연결되며, 해당 데이터는 보조 캐시에 복제됩니다.", - "waf": "신뢰도" - }, { "arm-service": "Microsoft.AVS/privateClouds", "checklist": "Azure VMware Solution Design Review", @@ -3742,528 +3702,160 @@ "waf": "신뢰도" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "스토리지와 관련된 Microsoft 클라우드 보안 벤치마크의 지침 적용", - "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", - "service": "Azure Storage", - "severity": "보통", - "text": "'스토리지에 대한 Azure 보안 기준' 고려", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Azure Service Bus 프리미엄은 미사용 데이터의 암호화를 제공합니다. 사용자 고유의 키를 사용하는 경우 데이터는 여전히 Microsoft 관리형 키를 사용하여 암호화되지만 Microsoft 관리형 키도 고객 관리형 키를 사용하여 암호화됩니다. ", + "guid": "87af4a79-1f89-439b-ba47-768e14c11567", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/configure-customer-managed-key", + "service": "Service Bus", + "severity": "낮다", + "text": "필요한 경우 미사용 데이터 암호화에서 고객 관리형 키 옵션을 사용합니다", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Azure Storage는 기본적으로 공용 IP 주소를 가지며 인터넷에 연결할 수 있습니다. 프라이빗 엔드포인트를 사용하면 액세스가 필요한 Azure Compute 리소스에만 Azure Storage를 안전하게 노출할 수 있으므로 공용 인터넷에 노출되지 않습니다", - "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", - "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", - "service": "Azure Storage", - "severity": "높다", - "text": "Azure Storage에 프라이빗 엔드포인트를 사용하는 것이 좋습니다.", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "클라이언트 애플리케이션과 Azure Service Bus 네임스페이스 간의 통신은 TLS(전송 계층 보안)를 사용하여 암호화됩니다. Azure Service Bus 네임스페이스를 사용하면 클라이언트가 TLS 1.0 이상을 사용하여 데이터를 보내고 받을 수 있습니다. 보다 엄격한 보안 조치를 적용하기 위해 클라이언트가 최신 버전의 TLS를 사용하여 데이터를 보내고 받도록 Service Bus 네임스페이스를 구성할 수 있습니다.", + "guid": "5c1ea55b-46a9-448f-b8ae-7d7e4b475b6c", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/transport-layer-security-enforce-minimum-version", + "service": "Service Bus", + "severity": "보통", + "text": "요청에 필요한 최소 버전의 TLS(전송 계층 보안) 적용 ", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "새로 만든 저장소 계정은 ARM 배포 모델을 사용하여 만들어지므로 RBAC, 감사 등을 모두 사용할 수 있습니다. 구독에 클래식 배포 모델이 있는 이전 저장소 계정이 없는지 확인합니다.", - "guid": "30e37c3e-2971-41b2-963c-eee079b598de", - "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", - "service": "Azure Storage", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Service Bus 네임스페이스를 만들면 네임스페이스에 대해 RootManageSharedAccessKey라는 SAS 규칙이 자동으로 만들어집니다. 이 정책에는 전체 네임스페이스에 대한 관리 권한이 있습니다. 이 규칙은 관리 루트 계정처럼 취급하고 애플리케이션에서 사용하지 않는 것이 좋습니다. RBAC에서 AAD를 인증 공급자로 사용하는 것이 좋습니다. ", + "guid": "8bcbf59b-ce65-4de8-a03f-97879468d66a", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", + "service": "Service Bus", "severity": "보통", - "text": "이전 스토리지 계정이 '클래식 배포 모델'을 사용하지 않는지 확인", + "text": "필요하지 않은 경우 루트 계정을 사용하지 마십시오.", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Microsoft Defender를 활용하여 의심스러운 활동 및 잘못된 구성에 대해 알아봅니다.", - "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", - "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", - "service": "Azure Storage", - "severity": "높다", - "text": "모든 스토리지 계정에 대해 Microsoft Defender 사용", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Azure 리소스 지원을 위해 관리되는 엔터티가 사용하도록 설정된 가상 머신 또는 Azure App Service 애플리케이션 내에서 실행되는 Service Bus 클라이언트 앱은 SAS 규칙 및 키 또는 기타 액세스 토큰을 처리할 필요가 없습니다. 클라이언트 앱에는 Service Bus 메시징 네임스페이스의 엔드포인트 주소만 필요합니다. ", + "guid": "786d60f9-6c96-4ad8-a55d-04c2b39c986b", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-managed-service-identity", + "service": "Service Bus", + "severity": "보통", + "text": "가능한 경우 애플리케이션은 관리 ID를 사용하여 Azure Service Bus에 인증해야 합니다. 그렇지 않은 경우 Azure Key Vault 또는 동등한 서비스에 스토리지 자격 증명(SAS, 서비스 주체 자격 증명)을 사용하는 것이 좋습니다", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "일시 삭제 메커니즘을 사용하면 실수로 삭제된 Blob을 복구할 수 있습니다.", - "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", - "service": "Azure Storage", - "severity": "보통", - "text": "Blob에 대해 '일시 삭제' 사용Enable 'soft delete' for blobs", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "사용 권한을 만들 때 Azure Service Bus에 대한 클라이언트의 액세스를 세밀하게 제어할 수 있습니다. Azure Service Bus의 사용 권한은 개별 리소스 수준(예: 큐, 토픽 또는 구독)으로 범위를 지정할 수 있으며 지정해야 합니다. ", + "guid": "f615658d-e558-4f93-9249-b831112dbd7e", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", + "service": "Service Bus", + "severity": "높다", + "text": "최소 권한 데이터 플레인 RBAC 사용", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "예를 들어 애플리케이션이 기밀성, 개인 정보 보호 또는 규정 준수를 위해 삭제된 정보가 즉시 삭제되도록 해야 하는 경우와 같이 특정 Blob 컨테이너에 대해 '일시 삭제'를 선택적으로 사용하지 않도록 설정하는 것이 좋습니다. ", - "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", - "service": "Azure Storage", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Azure Service Bus 리소스 로그에는 작업 로그, 가상 네트워크 및 IP 필터링 로그가 포함됩니다. 런타임 감사 로그는 Service Bus에서 다양한 데이터 평면 액세스 작업(예: 메시지 보내기 또는 받기)에 대해 집계된 진단 정보를 캡처합니다.", + "guid": "af12e7f9-43f6-4304-922d-929c2b1cd622", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", + "service": "Service Bus", "severity": "보통", - "text": "Blob에 대해 '일시 삭제' 사용 안 함", + "text": "보안 조사를 위해 로깅을 사용하도록 설정합니다. Azure Monitor를 사용하여 리소스 로그 및 런타임 감사 로그 추적(현재 프리미엄 계층에서만 사용 가능)", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "컨테이너에 대한 일시 삭제를 사용하면 컨테이너가 삭제된 후 컨테이너를 복구할 수 있습니다(예: 실수로 인한 삭제 작업에서 복구).", - "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", - "service": "Azure Storage", - "severity": "높다", - "text": "컨테이너에 대해 '일시 삭제' 사용Enable 'soft delete' for containers", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Azure Service Bus는 기본적으로 공용 IP 주소를 가지며 인터넷에 연결할 수 있습니다. 프라이빗 엔드포인트를 사용하면 가상 네트워크와 Azure Service Bus 간의 트래픽이 Microsoft 백본 네트워크를 통과할 수 있습니다. 또한 공용 엔드포인트를 사용하지 않는 경우 사용하지 않도록 설정해야 합니다. ", + "guid": "9ae669ca-48e4-4a85-b222-3ece8bb12307", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", + "service": "Service Bus", + "severity": "보통", + "text": "프라이빗 엔드포인트를 사용하여 Azure Service Bus에 액세스하고 해당하는 경우 공용 네트워크 액세스를 사용하지 않도록 설정하는 것이 좋습니다.", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "예를 들어 애플리케이션이 기밀성, 개인 정보 보호 또는 규정 준수를 위해 삭제된 정보가 즉시 삭제되도록 해야 하는 경우와 같이 특정 Blob 컨테이너에 대해 '일시 삭제'를 선택적으로 사용하지 않도록 설정하는 것이 좋습니다. ", - "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", - "service": "Azure Storage", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "IP 방화벽을 사용하면 퍼블릭 엔드포인트를 CIDR(Classless Inter-Domain Routing) 표기법의 IPv4 주소 집합 또는 IPv4 주소 범위로만 추가로 제한할 수 있습니다. ", + "guid": "ca5f06f1-58e3-4ea3-a92c-2de7e2165c3a", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-ip-filtering", + "service": "Service Bus", "severity": "보통", - "text": "컨테이너에 대해 '일시 삭제' 사용 안 함", + "text": "특정 IP 주소 또는 범위에서만 Azure Service Bus 네임스페이스에 액세스할 수 있도록 허용하는 것이 좋습니다", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "안전" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "사용자가 삭제하기 전에 먼저 삭제 잠금을 제거하도록 강제하여 저장소 계정이 실수로 삭제되는 것을 방지합니다.", - "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "cb26b2ba-a9db-45d1-8260-d9c6ec1447d9", + "link": "https://learn.microsoft.com/en-us/azure/logic-apps/single-tenant-overview-compare", + "service": "IoT Hub DPS", "severity": "높다", - "text": "스토리지 계정에 대한 리소스 잠금 사용Enable resource locks on storage accounts", - "waf": "안전" + "text": "비즈니스 및 SLO 요구 사항에 따라 올바른 Logic App 호스팅 계획 선택Select the right Logic App hosting plan based on your business & SLO requirements", + "waf": "신뢰도" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Blob에 대한 '법적 보존' 또는 '시간 기반 보존' 정책을 고려하면 Blob, 컨테이너 또는 스토리지 계정을 삭제할 수 없습니다. '불가능'은 실제로 '불가능'을 의미합니다. 스토리지 계정에 변경할 수 없는 Blob이 포함된 경우 해당 스토리지 계정을 '제거'하는 유일한 방법은 Azure 구독을 취소하는 것입니다.", - "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", - "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "f6dd7977-1123-4f39-b488-f91415a8430a", + "link": "https://learn.microsoft.com/en-us/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", + "service": "IoT Hub DPS", "severity": "높다", - "text": "변경할 수 없는 Blob 고려", - "waf": "안전" + "text": "영역 중복 및 가용성 영역을 사용하여 지역 오류로부터 논리 앱 보호Protect logic apps from region failures with zone redundancy and availability zones", + "waf": "신뢰도" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "모든 데이터 전송이 암호화되고, 무결성이 보호되고, 서버가 인증되도록 스토리지 계정에 대한 보호되지 않는 HTTP/80 액세스를 사용하지 않도록 설정하는 것이 좋습니다. ", - "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "8aed4fbf-0830-4883-899d-222a154af478", + "link": "https://learn.microsoft.com/en-us/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", + "service": "IoT Hub DPS", "severity": "높다", - "text": "HTTPS 필요, 즉 스토리지 계정에서 포트 80 사용 안 함Require HTTPS, i.e. disable port 80 on the storage account", - "waf": "안전" + "text": "중요한 워크로드에 대한 지역 간 DR 전략 고려", + "waf": "신뢰도" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "스토리지 계정에서 사용자 지정 도메인(호스트 이름)을 구성할 때 TLS/HTTPS가 필요한지 여부를 확인합니다. 이 경우 저장소 계정 앞에 Azure CDN을 배치해야 할 수 있습니다.", - "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", - "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "da0f033e-d180-4f36-9aa4-c468dba14203", + "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", + "service": "IoT Hub DPS", "severity": "높다", - "text": "HTTPS를 적용할 때(HTTP 사용 안 함) 스토리지 계정에 사용자 지정 도메인(CNAME)을 사용하지 않는지 확인합니다.", - "waf": "안전" + "text": "격리된 환경에 배포하는 경우 ASE(App Service Environment) v3을 사용하거나 마이그레이션합니다", + "waf": "신뢰도" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "클라이언트가 SAS 토큰을 사용하여 Blob 데이터에 액세스할 때 HTTPS를 요구하면 자격 증명 손실 위험을 최소화하는 데 도움이 됩니다.", - "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "62711604-c9d1-4b0a-bdb7-5fda54a4f6c1", + "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", + "service": "IoT Hub DPS", "severity": "보통", - "text": "SAS(공유 액세스 서명) 토큰을 HTTPS 연결로만 제한", - "waf": "안전" + "text": "Azure DevOps 또는 GitHub를 활용하여 CI/CD를 간소화하고 논리 앱 코드를 보호합니다.", + "waf": "작업" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "AAD 토큰은 가능한 경우 공유 액세스 서명보다 우선해야 합니다", - "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", - "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", - "service": "Azure Storage", + "arm-service": "Microsoft.Search/searchServices", + "checklist": "Cognitive Search Review Checklist", + "guid": "41faa1ed-b7f0-447d-8cba-4a4905e5bb83", + "link": "https://learn.microsoft.com/azure/search/search-reliability#high-availability", + "service": "Cognitive Search", "severity": "높다", - "text": "Blob 액세스에 Azure AD(Azure Active Directory) 토큰 사용Use Azure Active Directory (Azure AD) tokens for blob access", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "사용자, 그룹 또는 응용 프로그램에 역할을 할당할 때 해당 보안 주체가 작업을 수행하는 데 필요한 권한만 부여합니다. 리소스에 대한 액세스를 제한하면 의도하지 않은 데이터 오용과 악의적인 데이터 오용을 모두 방지할 수 있습니다.", - "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", - "service": "Azure Storage", - "severity": "보통", - "text": "IaM 권한의 최소 권한", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "사용자 위임 SAS는 Azure AD(Azure Active Directory) 자격 증명과 SAS에 지정된 권한으로 보호됩니다. 사용자 위임 SAS는 범위와 기능 측면에서 서비스 SAS와 유사하지만 서비스 SAS에 비해 보안상의 이점을 제공합니다. ", - "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", - "service": "Azure Storage", - "severity": "높다", - "text": "SAS를 사용하는 경우 스토리지 계정 키 기반 SAS보다 '사용자 위임 SAS'를 선호합니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "스토리지 계정 키('공유 키')에는 감사 기능이 거의 없습니다. 누가/언제 키 사본을 가져왔는지 모니터링할 수 있지만, 키가 여러 사람의 손에 들어가면 특정 사용자의 사용을 귀속시키는 것은 불가능합니다. AAD 인증에만 의존하면 스토리지 액세스를 사용자에게 더 쉽게 연결할 수 있습니다. ", - "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", - "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", - "service": "Azure Storage", - "severity": "높다", - "text": "AAD 액세스(및 사용자 위임 SAS)만 지원되도록 스토리지 계정 키를 사용하지 않도록 설정하는 것이 좋습니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "활동 로그 데이터를 사용하여 스토리지 계정의 보안을 보거나 변경하는 '시기', '누가', '무엇을' 및 '방법'(예: 스토리지 계정 키, 액세스 정책 등)을 식별합니다.", - "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", - "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", - "service": "Azure Storage", - "severity": "높다", - "text": "Azure Monitor를 사용하여 스토리지 계정에 대한 컨트롤 플레인 작업을 감사하는 것이 좋습니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "키 만료 정책을 사용하면 계정 액세스 키 교체에 대한 미리 알림을 설정할 수 있습니다. 지정된 간격이 경과하고 키가 아직 회전되지 않은 경우 알림이 표시됩니다.", - "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", - "service": "Azure Storage", - "severity": "보통", - "text": "스토리지 계정 키를 사용하는 경우 '키 만료 정책'을 사용하도록 설정하는 것이 좋습니다", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS 만료 정책은 SAS가 유효한 권장 간격을 지정합니다. SAS 만료 정책은 서비스 SAS 또는 계정 SAS에 적용됩니다. 사용자가 권장 간격보다 큰 유효 간격을 사용하여 서비스 SAS 또는 계정 SAS를 생성하면 경고가 표시됩니다.", - "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", - "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", - "service": "Azure Storage", - "severity": "보통", - "text": "SAS 만료 정책 구성 고려", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "저장된 액세스 정책은 스토리지 계정 키를 다시 생성할 필요 없이 서비스 SAS에 대한 권한을 취소하는 옵션을 제공합니다. ", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", - "service": "Azure Storage", - "severity": "보통", - "text": "SAS를 저장된 액세스 정책에 연결하는 것이 좋습니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", - "service": "Azure Storage", - "severity": "보통", - "text": "체크 인된 연결 문자열 및 저장소 계정 키를 검색하도록 응용 프로그램의 소스 코드 리포지토리를 구성하는 것이 좋습니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "이상적으로 애플리케이션은 관리 ID를 사용하여 Azure Storage에 인증해야 합니다. 이렇게 할 수 없는 경우 Azure KeyVault 또는 동등한 서비스에 스토리지 자격 증명(연결 문자열, 스토리지 계정 키, SAS, 서비스 주체 자격 증명)을 사용하는 것이 좋습니다.", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", - "service": "Azure Storage", - "severity": "높다", - "text": "Azure KeyVault에 연결 문자열을 저장하는 것이 좋습니다(관리 ID를 사용할 수 없는 시나리오에서).", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "임시 SAS 서비스 SAS 또는 계정 SAS에서 단기 만료 시간을 사용합니다. 이러한 방식으로 SAS가 손상되더라도 짧은 시간 동안만 유효합니다. 이 방법은 저장된 액세스 정책을 참조할 수 없는 경우에 특히 중요합니다. 또한 단기 만료 시간은 업로드에 사용할 수 있는 시간을 제한하여 Blob에 쓸 수 있는 데이터의 양을 제한합니다.", - "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", - "severity": "높다", - "text": "임시 SAS의 유효 기간을 단축하기 위해 노력", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS를 만들 때는 가능한 한 구체적이고 제한적이어야 합니다. 훨씬 더 광범위한 액세스를 제공하는 SAS보다 단일 리소스 및 작업에 대해 SAS를 선호합니다.", - "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", - "severity": "보통", - "text": "SAS에 좁은 범위 적용", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS에는 SAS를 사용하여 리소스를 요청할 수 있는 권한이 있는 클라이언트 IP 주소 또는 주소 범위에 대한 매개 변수가 포함될 수 있습니다. ", - "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", - "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", - "service": "Azure Storage", - "severity": "보통", - "text": "가능한 경우 SAS의 범위를 특정 클라이언트 IP 주소로 지정하는 것이 좋습니다", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS는 클라이언트가 업로드하는 데이터의 양을 제한할 수 없습니다. 시간 경과에 따른 스토리지 양의 가격 책정 모델을 고려할 때 클라이언트가 악의적으로 큰 콘텐츠를 업로드했는지 여부를 확인하는 것이 합리적일 수 있습니다.", - "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", - "service": "Azure Storage", - "severity": "낮다", - "text": "클라이언트가 SAS를 사용하여 파일을 업로드한 후 업로드된 데이터를 확인하는 것이 좋습니다. ", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "'로컬 사용자 계정'을 사용하여 SFTP를 통해 Blob Storage에 액세스하는 경우 '일반적인' RBAC 컨트롤이 적용되지 않습니다. NFS 또는 REST를 통한 Blob 액세스는 SFTP 액세스보다 더 제한적일 수 있습니다. 안타깝게도 2023년 초부터 로컬 사용자는 현재 SFTP 엔드포인트에 대해 지원되는 유일한 ID 관리 형태입니다", - "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", - "service": "Azure Storage", - "severity": "높다", - "text": "SFTP: SFTP 액세스에 대한 '로컬 사용자'의 수를 제한하고 시간이 지남에 따라 액세스가 필요한지 여부를 감사합니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", - "service": "Azure Storage", - "severity": "보통", - "text": "SFTP: SFTP 엔드포인트는 POSIX와 유사한 ACL을 지원하지 않습니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "스토리지는 CORS(Cross-Origin Resource Sharing), 즉 다른 도메인의 웹앱이 동일 출처 정책을 완화할 수 있도록 하는 HTTP 기능을 지원합니다. CORS를 사용하도록 설정할 때 CorsRules를 최소 권한으로 유지합니다.", - "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", - "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", - "service": "Azure Storage", - "severity": "높다", - "text": "지나치게 광범위한 CORS 정책 방지", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "미사용 데이터는 항상 서버 쪽에서 암호화되며 클라이언트 쪽에서도 암호화될 수 있습니다. 서버 쪽 암호화는 플랫폼 관리형 키(기본값) 또는 고객 관리형 키를 사용하여 발생할 수 있습니다. 클라이언트 쪽 암호화는 클라이언트가 Azure Storage에 Blob별로 암호화/암호 해독 키를 제공하거나 클라이언트 쪽에서 암호화를 완전히 처리하여 발생할 수 있습니다. 따라서 기밀성 보장을 위해 Azure Storage에 전혀 의존하지 않습니다.", - "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", - "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", - "service": "Azure Storage", - "severity": "높다", - "text": "미사용 데이터를 암호화하는 방법을 결정합니다. 데이터에 대한 스레드 모델을 이해합니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", - "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", - "service": "Azure Storage", - "severity": "보통", - "text": "사용해야 하는 플랫폼 암호화를 결정합니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", - "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", - "service": "Azure Storage", - "severity": "보통", - "text": "사용해야 하는 클라이언트 쪽 암호화를 결정합니다.", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Resource Graph Explorer(resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true)를 활용하여 익명 Blob 액세스를 허용하는 스토리지 계정을 찾습니다.", - "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", - "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", - "service": "Azure Storage", - "severity": "높다", - "text": "공용 Blob 액세스가 필요한지 또는 특정 스토리지 계정에 대해 사용하지 않도록 설정할 수 있는지 여부를 고려합니다. ", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Azure Service Bus 프리미엄은 미사용 데이터의 암호화를 제공합니다. 사용자 고유의 키를 사용하는 경우 데이터는 여전히 Microsoft 관리형 키를 사용하여 암호화되지만 Microsoft 관리형 키도 고객 관리형 키를 사용하여 암호화됩니다. ", - "guid": "87af4a79-1f89-439b-ba47-768e14c11567", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/configure-customer-managed-key", - "service": "Service Bus", - "severity": "낮다", - "text": "필요한 경우 미사용 데이터 암호화에서 고객 관리형 키 옵션을 사용합니다", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "클라이언트 애플리케이션과 Azure Service Bus 네임스페이스 간의 통신은 TLS(전송 계층 보안)를 사용하여 암호화됩니다. Azure Service Bus 네임스페이스를 사용하면 클라이언트가 TLS 1.0 이상을 사용하여 데이터를 보내고 받을 수 있습니다. 보다 엄격한 보안 조치를 적용하기 위해 클라이언트가 최신 버전의 TLS를 사용하여 데이터를 보내고 받도록 Service Bus 네임스페이스를 구성할 수 있습니다.", - "guid": "5c1ea55b-46a9-448f-b8ae-7d7e4b475b6c", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/transport-layer-security-enforce-minimum-version", - "service": "Service Bus", - "severity": "보통", - "text": "요청에 필요한 최소 버전의 TLS(전송 계층 보안) 적용 ", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Service Bus 네임스페이스를 만들면 네임스페이스에 대해 RootManageSharedAccessKey라는 SAS 규칙이 자동으로 만들어집니다. 이 정책에는 전체 네임스페이스에 대한 관리 권한이 있습니다. 이 규칙은 관리 루트 계정처럼 취급하고 애플리케이션에서 사용하지 않는 것이 좋습니다. RBAC에서 AAD를 인증 공급자로 사용하는 것이 좋습니다. ", - "guid": "8bcbf59b-ce65-4de8-a03f-97879468d66a", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", - "service": "Service Bus", - "severity": "보통", - "text": "필요하지 않은 경우 루트 계정을 사용하지 마십시오.", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Azure 리소스 지원을 위해 관리되는 엔터티가 사용하도록 설정된 가상 머신 또는 Azure App Service 애플리케이션 내에서 실행되는 Service Bus 클라이언트 앱은 SAS 규칙 및 키 또는 기타 액세스 토큰을 처리할 필요가 없습니다. 클라이언트 앱에는 Service Bus 메시징 네임스페이스의 엔드포인트 주소만 필요합니다. ", - "guid": "786d60f9-6c96-4ad8-a55d-04c2b39c986b", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-managed-service-identity", - "service": "Service Bus", - "severity": "보통", - "text": "가능한 경우 애플리케이션은 관리 ID를 사용하여 Azure Service Bus에 인증해야 합니다. 그렇지 않은 경우 Azure Key Vault 또는 동등한 서비스에 스토리지 자격 증명(SAS, 서비스 주체 자격 증명)을 사용하는 것이 좋습니다", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "사용 권한을 만들 때 Azure Service Bus에 대한 클라이언트의 액세스를 세밀하게 제어할 수 있습니다. Azure Service Bus의 사용 권한은 개별 리소스 수준(예: 큐, 토픽 또는 구독)으로 범위를 지정할 수 있으며 지정해야 합니다. ", - "guid": "f615658d-e558-4f93-9249-b831112dbd7e", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", - "service": "Service Bus", - "severity": "높다", - "text": "최소 권한 데이터 플레인 RBAC 사용", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Azure Service Bus 리소스 로그에는 작업 로그, 가상 네트워크 및 IP 필터링 로그가 포함됩니다. 런타임 감사 로그는 Service Bus에서 다양한 데이터 평면 액세스 작업(예: 메시지 보내기 또는 받기)에 대해 집계된 진단 정보를 캡처합니다.", - "guid": "af12e7f9-43f6-4304-922d-929c2b1cd622", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", - "service": "Service Bus", - "severity": "보통", - "text": "보안 조사를 위해 로깅을 사용하도록 설정합니다. Azure Monitor를 사용하여 리소스 로그 및 런타임 감사 로그 추적(현재 프리미엄 계층에서만 사용 가능)", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Azure Service Bus는 기본적으로 공용 IP 주소를 가지며 인터넷에 연결할 수 있습니다. 프라이빗 엔드포인트를 사용하면 가상 네트워크와 Azure Service Bus 간의 트래픽이 Microsoft 백본 네트워크를 통과할 수 있습니다. 또한 공용 엔드포인트를 사용하지 않는 경우 사용하지 않도록 설정해야 합니다. ", - "guid": "9ae669ca-48e4-4a85-b222-3ece8bb12307", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", - "service": "Service Bus", - "severity": "보통", - "text": "프라이빗 엔드포인트를 사용하여 Azure Service Bus에 액세스하고 해당하는 경우 공용 네트워크 액세스를 사용하지 않도록 설정하는 것이 좋습니다.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "IP 방화벽을 사용하면 퍼블릭 엔드포인트를 CIDR(Classless Inter-Domain Routing) 표기법의 IPv4 주소 집합 또는 IPv4 주소 범위로만 추가로 제한할 수 있습니다. ", - "guid": "ca5f06f1-58e3-4ea3-a92c-2de7e2165c3a", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-ip-filtering", - "service": "Service Bus", - "severity": "보통", - "text": "특정 IP 주소 또는 범위에서만 Azure Service Bus 네임스페이스에 액세스할 수 있도록 허용하는 것이 좋습니다", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "cb26b2ba-a9db-45d1-8260-d9c6ec1447d9", - "link": "https://learn.microsoft.com/en-us/azure/logic-apps/single-tenant-overview-compare", - "service": "IoT Hub DPS", - "severity": "높다", - "text": "비즈니스 및 SLO 요구 사항에 따라 올바른 Logic App 호스팅 계획 선택Select the right Logic App hosting plan based on your business & SLO requirements", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "f6dd7977-1123-4f39-b488-f91415a8430a", - "link": "https://learn.microsoft.com/en-us/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", - "service": "IoT Hub DPS", - "severity": "높다", - "text": "영역 중복 및 가용성 영역을 사용하여 지역 오류로부터 논리 앱 보호Protect logic apps from region failures with zone redundancy and availability zones", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "8aed4fbf-0830-4883-899d-222a154af478", - "link": "https://learn.microsoft.com/en-us/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", - "service": "IoT Hub DPS", - "severity": "높다", - "text": "중요한 워크로드에 대한 지역 간 DR 전략 고려", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "da0f033e-d180-4f36-9aa4-c468dba14203", - "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", - "service": "IoT Hub DPS", - "severity": "높다", - "text": "격리된 환경에 배포하는 경우 ASE(App Service Environment) v3을 사용하거나 마이그레이션합니다", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "62711604-c9d1-4b0a-bdb7-5fda54a4f6c1", - "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", - "service": "IoT Hub DPS", - "severity": "보통", - "text": "Azure DevOps 또는 GitHub를 활용하여 CI/CD를 간소화하고 논리 앱 코드를 보호합니다.", - "waf": "작업" - }, - { - "arm-service": "Microsoft.Search/searchServices", - "checklist": "Cognitive Search Review Checklist", - "guid": "41faa1ed-b7f0-447d-8cba-4a4905e5bb83", - "link": "https://learn.microsoft.com/azure/search/search-reliability#high-availability", - "service": "Cognitive Search", - "severity": "높다", - "text": "읽기 작업에 대해 99.9%의 가용성을 갖도록 복제본 2개 사용", - "waf": "신뢰도" + "text": "읽기 작업에 대해 99.9%의 가용성을 갖도록 복제본 2개 사용", + "waf": "신뢰도" }, { "arm-service": "Microsoft.Search/searchServices", @@ -4325,6 +3917,46 @@ "text": "Azure Cognitive Search 인덱스를 백업 및 복원합니다. 이 샘플 코드를 사용하여 인덱스 정의 및 스냅샷을 일련의 Json 파일에 백업합니다", "waf": "신뢰도" }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "높다", + "text": "Azure Cache for Redis에 대한 영역 중복을 사용하도록 설정합니다. Azure Cache for Redis는 프리미엄 및 엔터프라이즈 계층에서 영역 중복 구성을 지원합니다. 영역 중복 캐시는 동일한 지역의 여러 Azure 가용성 영역에 노드를 배치할 수 있습니다. 데이터 센터 또는 AZ 중단을 단일 장애 지점으로 제거하고 캐시의 전반적인 가용성을 높입니다.", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "보통", + "text": "Azure Cache for Redis 인스턴스에 대한 데이터 지속성을 구성합니다. 캐시 데이터가 메모리에 저장되기 때문에 여러 노드의 드물고 계획되지 않은 오류로 인해 모든 데이터가 삭제될 수 있습니다. 데이터가 완전히 손실되는 것을 방지하기 위해 Redis 지속성을 사용하면 메모리 내 데이터의 주기적인 스냅샷을 만들고 스토리지 계정에 저장할 수 있습니다.", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "보통", + "text": "지역 중복 스토리지 계정을 사용하여 Azure Cache for Redis 데이터를 유지하거나 지역 중복을 사용할 수 없는 경우 영역 중복을 사용합니다.", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "보통", + "text": "프리미엄 Azure Cache for Redis 인스턴스에 대한 수동 지역 복제를 구성합니다. 지역에서 복제는 일반적으로 두 개의 Azure 지역에 걸쳐 있는 두 개 이상의 Azure Cache for Redis 인스턴스를 연결하는 메커니즘입니다. 지역에서 복제는 주로 지역 간 재해 복구를 위해 설계되었습니다. 두 개의 프리미엄 계층 캐시 인스턴스는 주 캐시에 대한 읽기 및 쓰기를 제공하는 방식으로 지역 복제를 통해 연결되며, 해당 데이터는 보조 캐시에 복제됩니다.", + "waf": "신뢰도" + }, { "arm-service": "Microsoft.BotService/botServices", "checklist": "Azure Bot Service", @@ -5928,14 +5560,216 @@ "waf": "신뢰도" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "graph": "resources| where type =~ 'microsoft.keyvault/vaults' | extend compliant = (properties.enableRbacAuthorization == true) | distinct id, compliant", - "guid": "d0642c1c-312b-4116-94ab-439e1c836819", - "link": "https://learn.microsoft.com/azure/key-vault/general/rbac-guide?tabs=azure-cli", - "service": "Key Vault", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "graph": "resources| where type =~ 'microsoft.keyvault/vaults' | extend compliant = (properties.enableRbacAuthorization == true) | distinct id, compliant", + "guid": "d0642c1c-312b-4116-94ab-439e1c836819", + "link": "https://learn.microsoft.com/azure/key-vault/general/rbac-guide?tabs=azure-cli", + "service": "Key Vault", + "severity": "보통", + "text": "RBAC는 키 자격 증명 모음에 대한 액세스를 제어하는 데 권장됩니다. Key Vault의 액세스 제어 지침을 숙지합니다.", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "데이터 반출을 방지하기 위해 이미지 내보내기를 비활성화합니다. 이렇게 하면 이미지를 다른 ACR 인스턴스로 가져올 수 없습니다.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "높다", + "text": "Azure Container Registry 이미지 내보내기 사용 안 함", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry에 대해 Azure Policy를 사용하도록 설정하여 감사 규정 준수 가시성 사용Enable audit compliance visibility by enabling Azure Policy for Azure Container Registry", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "높다", + "text": "Azure Container Registry에 대한 Azure 정책 사용", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "AKV(Azure Key Vault)는 컨테이너 이미지 및 기타 아티팩트에 서명하고 확인하기 위해 AKV 플러그 인(azure-kv) 표기법과 함께 사용할 수 있는 서명 키를 저장하는 데 사용됩니다. ACR(Azure Container Registry)을 사용하면 ?az?또는?oras? CLI 명령.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "높다", + "text": "표기법을 사용하여 컨테이너 서명 및 확인(Notary v2)", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Container Registry는 저장하는 이미지 및 기타 아티팩트를 자동으로 암호화합니다. 기본적으로 Azure는 서비스 관리형 키를 사용하여 미사용 레지스트리 콘텐츠를 자동으로 암호화합니다. 고객 관리형 키를 사용하면 추가 암호화 계층으로 기본 암호화를 보완할 수 있습니다.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "보통", + "text": "고객 관리형 키로 레지스트리 암호화Encrypt registry with a customer managed key", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "관리 ID를 사용하여 클라이언트 애플리케이션에서 ACRPull/Push RBAC 액세스 보호", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "높다", + "text": "서비스 주체 대신 관리 ID를 사용하여 연결", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "로컬 관리자 계정은 기본적으로 사용하지 않도록 설정되어 있으며 사용하도록 설정해서는 안 됩니다. 대신 토큰 또는 RBAC 기반 액세스 방법을 사용합니다.", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "높다", + "text": "관리부 액세스에 대한 로컬 인증 사용 안 함Disable local authentication for management plane access", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "관리자 계정을 사용하지 않도록 설정하고 ACR 끌어오기/푸시 작업을 위해 보안 주체에 RBAC 역할을 할당합니다.", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "높다", + "text": "ID 주체에 대한 관리 액세스 권한을 부여하는 대신 AcrPull 및 AcrPush RBAC 역할을 할당합니다.", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "익명 끌어오기/밀어넣기 액세스 사용 안 함Disable anonymous pull/push access", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "보통", + "text": "익명 끌어오기 액세스 사용 안 함Disable Anonymous pull access", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "토큰 인증은 AAD 보안 주체에 대한 할당을 지원하지 않습니다. 제공된 모든 토큰은 토큰에 액세스할 수 있는 모든 사람이 사용할 수 있습니다", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "높다", + "text": "리포지토리 범위 액세스 토큰 사용 안 함Disable repository-scoped access tokens", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "신뢰할 수 있는 네트워크 내의 프라이빗 엔드포인트 뒤에 있는 ACR에 컨테이너 이미지 배포Deploy container images to an ACR behind a Private endpoint within a trusted network", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "높다", + "text": "신뢰할 수 있는 환경에서 이미지 배포", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "ACR 대상이 있는 토큰만 인증에 사용할 수 있습니다. ACR에 대한 조건부 액세스 정책을 사용하도록 설정할 때 사용됩니다.", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "보통", + "text": "인증을 위해 Azure ARM 대상 토큰 사용 안 함", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "'repositoryEvents' 및 'LoginEvents'를 로깅 및 모니터링의 중앙 대상으로 Log Analytics에 보내도록 진단 설정을 지정합니다. 이렇게 하면 ACR 리소스 자체에 대한 컨트롤 플레인 작업을 모니터링할 수 있습니다.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "보통", + "text": "진단 로깅 사용Enable diagnostics logging", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "서비스는 서비스 수준 IP ACL 필터링 규칙(NSG 또는 Azure Firewall 아님)을 사용하거나 '공용 네트워크 액세스 사용 안 함' 토글 스위치를 사용하여 공용 네트워크 액세스를 사용하지 않도록 지원합니다", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "보통", + "text": "Private Link를 사용하여 인바운드 네트워크 액세스 제어", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Private Link를 사용하여 인바운드 네트워크 액세스가 보호되는 경우 공용 네트워크 액세스 사용 안 함", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "보통", + "text": "공용 네트워크 액세스 사용 안 함", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "ACR Premium SKU만 Private Link 액세스를 지원합니다.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "보통", + "text": "Private Link(프리미엄 SKU)를 지원하는 Azure Container Registry SKU 사용", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "컨테이너용 Azure Defender 또는 동등한 서비스를 사용하여 컨테이너 이미지의 취약성을 검사해야 합니다.", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "낮다", + "text": "컨테이너용 Defender를 사용하여 Azure Container Registry에서 취약성을 검사하도록 설정", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "DevSecOps 사례에 따라 취약성을 검증하고 스캔한 신뢰할 수 있는 코드를 배포합니다.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", "severity": "보통", - "text": "RBAC는 키 자격 증명 모음에 대한 액세스를 제어하는 데 권장됩니다. Key Vault의 액세스 제어 지침을 숙지합니다.", + "text": "유효성이 검사된 컨테이너 이미지 배포", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "지원되는 플랫폼, 프로그래밍 언어, 프로토콜 및 프레임워크의 최신 버전을 사용합니다.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "높다", + "text": "최신 플랫폼, 언어, 프로토콜 및 프레임워크 사용", "waf": "안전" }, { @@ -6556,6 +6390,17 @@ "text": "Synapse의 SQL 워크로드에서 로컬 사용자 사용 제한", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "기본 배포에서 사용하도록 설정되므로 추가 구성이 필요하지 않습니다.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "전송 중인 민감한 데이터 암호화", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6567,6 +6412,15 @@ "text": "관리 ID를 사용하여 서비스에 인증", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "기본적으로 미사용 데이터 암호화 사용Enable data at rest encryption by default", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6577,6 +6431,17 @@ "text": "높은 권한이 부여된/관리 사용자를 분리 및 제한하고 MFA 및 조건부 정책을 사용하도록 설정합니다.", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Keyvaults를 사용하여 CMK 저장", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "필요한 경우 미사용 데이터 암호화에서 고객 관리형 키 옵션을 사용합니다.", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6609,6 +6474,16 @@ "text": "관리되는 vnet 작업 영역을 사용하여 공용 인터넷을 통한 액세스 제한", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Microsoft Entra ID를 기본 인증 방법으로 사용합니다.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "severity": "높다", + "text": "Microsoft Entra ID를 기본 인증 방법으로 사용하고 가능한 경우 로컬 액세스를 사용하지 않도록 설정합니다.", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6620,6 +6495,16 @@ "text": "외부 서비스에 연결하고 공용 액세스를 사용하지 않도록 프라이빗 엔드포인트를 구성합니다.", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Microsoft Entra ID를 기본 인증 방법으로 사용합니다.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "관리 ID를 사용하여 서비스에 인증", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6630,6 +6515,15 @@ "text": "공용 액세스를 사용하도록 설정하는 경우 IP 방화벽 규칙을 구성하는 것이 좋습니다.", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "데이터 플레인에 대한 액세스를 제한하는 조건부 액세스 정책 구성Configure conditional access policies to restrict access on the Data plane", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6640,6 +6534,16 @@ "text": "회사 네트워크를 벗어나지 않아야 하는 중요한 데이터로 작업하는 경우 VN에 SHIR VM을 배포합니다.", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "키 및 인증서 노출 제한", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "severity": "높다", + "text": "Azure Key Vault를 사용하여 비밀 및 크레센셜을 저장합니다.", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6651,6 +6555,37 @@ "text": "DEP(데이터 반출 보호) 사용", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "severity": "높다", + "text": "높은 권한이 있는 사용자/관리 사용자 분리 및 제한", + "waf": "안전" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Event Hubs 네임스페이스를 만들면 네임스페이스에 대해 RootManageSharedAccessKey라는 정책 규칙이 자동으로 만들어집니다. 이 정책에는 전체 네임스페이스에 대한 관리 권한이 있습니다. 이 규칙을 관리 루트 계정처럼 취급하고 응용 프로그램에서 사용하지 않는 것이 좋습니다. PowerShell 또는 Azure CLI를 통해 포털의 네임스페이스에 대한 구성 탭에서 추가 정책 규칙을 만들 수 있습니다. 로컬 인증 방법 또는 계정을 사용하지 말고 가능한 한 사용하지 않도록 설정해야 합니다. 대신 가능한 경우 Azure AD를 사용하여 인증합니다.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "SAS(공유 액세스 서명)를 사용하여 Event Hubs 리소스에 대한 액세스를 인증하고 로컬 사용자를 제한합니다.", + "waf": "안전" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure RBAC(Azure 역할 기반 액세스 제어)를 사용하여 기본 제공 역할 할당을 통해 Azure 리소스 액세스를 관리합니다. Azure RBAC 역할은 사용자, 그룹, 서비스 주체 및 관리 ID에 할당할 수 있습니다.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "Azure RBAC를 사용하여 액세스 세분화 ", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6662,6 +6597,16 @@ "text": "작업 영역에 대한 고객 관리형 키를 사용한 미사용 데이터 암호화Data Encryption at rest using Customer managed Keys for workspace", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "서비스는 서비스 수준 IP ACL 필터링 규칙(NSG 또는 Azure Firewall 아님)을 사용하거나 '공용 네트워크 액세스 사용 안 함' 토글 스위치를 사용하여 공용 네트워크 액세스를 사용하지 않도록 설정할 수 있도록 지원합니다.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "공용 네트워크 액세스 사용 안 함", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6673,6 +6618,15 @@ "text": "전송 중 데이터 암호화 ", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "Vnet을 사용하여 제한된 네트워크를 통한 트래픽 격리 ", + "waf": "안전" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6683,6 +6637,111 @@ "text": "Azure Key Vault에 암호, secerts 및 키 저장Store passwords, secerts and keys in Azure key vault", "waf": "안전" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "보통", + "text": "Private Link 기능을 지원하는 모든 Azure 리소스에 대한 프라이빗 엔드포인트를 배포하여 리소스에 대한 프라이빗 액세스 지점을 설정합니다.", + "waf": "안전" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure Key Vault에 자격 증명 또는 비밀 값을 저장하고 파이프라인 실행 중에 사용하여 활동에 전달할 수 있습니다.", + "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "보통", + "text": "파이프라인 활동에서 Azure Key Vault 비밀 사용Use Azure Key Vault secrets in pipeline activities", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric은 작업 영역을 사용하여 데이터 액세스를 제어합니다. 작업공간에서 데이터는 패브릭 항목의 형태로 표시되며, 사용자는 작업공간에 대한 액세스 권한을 부여하지 않는 한 항목(데이터)을 보거나 사용할 수 없습니다. 작업 영역 및 항목 권한에 대한 자세한 내용은 사용 권한 모델에서 확인할 수 있습니다.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "작업 영역 역할을 사용하여 사용자에게 데이터에 대한 액세스 권한 제공", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "OneLake RBAC는 역할 할당을 사용하여 구성원에게 권한을 적용합니다.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "Onelake에서 RBAC를 사용하여 테이블/파일 Onelake의 데이터에 대한 세분화된 액세스를 제공합니다. ", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "바로 가기의 대상 위치와 원본 위치 모두에서 사용자의 액세스를 고려합니다.", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "바로 가기를 사용하는 경우 사용자의 사용자 ID는 바로 가기의 대상 위치에도 액세스할 수 있어야 합니다", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "모든 사용자가 역할을 사용하여 전체 워크스페이스에 액세스할 필요가 있는 것은 아니므로 대신 전체 워크스페이스에 대한 역할 부여를 제한하고 항목 공유 기능 또는 Fabric의 관리 권한을 사용하여 사용자에게만 항목을 공유합니다.", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "작업 영역 수준 역할을 사용자에게 제공하는 것을 제한하는 대신 사용자에게만 항목을 공유합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "RLS, CLS 및 동적 데이터 마스킹과 같은 기능을 사용하여 SQL 워크로드에 대한 데이터 보안 요구 사항을 강화합니다.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "웨어하우스 및 SQL 분석 엔드포인트에서 RLS, CLS 및 동적 데이터 마스킹을 정의하여 데이터에 대한 액세스를 제한합니다.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Power BI에서 RLS 및 OLS와 같은 기능을 사용하여 의미 체계 모델에 더 많은 보안 기능을 사용할 수 있습니다.", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "Power BI의 의미 체계 모델에서 RLS 및 OLS를 정의하여 데이터에 대한 액세스를 제한합니다.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric에서 OneLake에 저장된 모든 데이터는 미사용 시 암호화됩니다", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "미사용 데이터 암호화", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Microsoft 서비스 간에 공용 인터넷을 통해 전송되는 데이터는 항상 TLS 1.2 이상으로 암호화됩니다. 패브릭은 가능할 때마다 TLS 1.3으로 협상합니다.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "전송 중인 데이터 암호화", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6693,6 +6752,16 @@ "text": "필요한 경우 로컬 사용자 사용 제한", "waf": "안전" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "아무 것도 할 필요가 없습니다. Fabric에 대한 모든 연결 요청은 Microsoft Entra ID로 인증되므로 사용자는 회사 사무실, 집에서 작업 할 때 또는 원격 위치에서 Fabric에 안전하게 연결할 수 있습니다.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "Microsoft Entra ID를 기본 인증 방법으로 사용", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6704,6 +6773,16 @@ "text": "관리 ID를 사용하여 서비스에 인증", "waf": "안전" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric 워크스페이스 ID는 Fabric 워크스페이스와 연관될 수 있는 자동으로 관리되는 서비스 프린시펄입니다. 작업 영역 ID는 내 작업 영역을 제외한 모든 작업 영역의 작업 영역 설정에서 만들 수 있습니다. 작업 영역 ID에는 작업 영역 기여자 역할이 자동으로 할당되고 작업 영역 항목에 액세스할 수 있습니다. 제한 사항: 작업 영역 ID를 인증 방법으로 사용할 때 바로 가기 대상에 쓰기가 실패합니다. workspace-identity-authentication을 사용한 연결은 Onelake 바로 가기 및 데이터 파이프라인에서만 사용할 수 있습니다.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "작업 영역 ID를 사용하여 서비스에 인증", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6714,6 +6793,35 @@ "text": "높은 권한이 부여된/관리 사용자를 분리 및 제한하고 MFA 및 조건부 정책을 사용하도록 설정합니다.", "waf": "안전" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "스토리지 계정에 대한 ID 권한 부여Grant the identity permissions on the storage account", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "스토리지 계정에 대한 RBAC 역할을 관리 ID에 제공하여 성공적인 연결을 만듭니다.", + "waf": "안전" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "service": "Azure Data Factory", + "severity": "보통", + "text": "공용 인터넷을 통한 액세스를 비활성화하고 방화벽 규칙 또는 신뢰할 수 있는 서비스 규칙을 구성합니다.", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "작업 영역 ID가 있는 패브릭 작업 영역은 OneLake 바로 가기에 대한 신뢰할 수 있는 작업 영역 액세스를 통해 방화벽 지원 Azure Data Lake Storage Gen2 계정을 안전하게 읽거나 쓸 수 있습니다.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "방화벽 뒤의 스토리지 계정에 액세스하기 위해 신뢰할 수 있는 작업 영역 액세스 구성Configure trusted workspace access to access storage account behind firewall ", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6723,6 +6831,17 @@ "text": "회사 네트워크를 벗어나지 않아야 하는 중요한 데이터로 작업하는 경우 VN에 SHIR VM을 배포합니다.", "waf": "안전" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "관리되는 가상 네트워크는 각 패브릭 작업 영역에 대해 Microsoft 패브릭에서 만들고 관리하는 가상 네트워크입니다. 관리형 가상 네트워크는 Fabric Spark 워크로드에 대한 네트워크 격리를 제공하며, 이는 컴퓨팅 클러스터가 전용 네트워크에 배포되고 더 이상 공유 가상 네트워크의 일부가 아님을 의미합니다. Fabric의 Spark 워크로드에 대해서만 지원됩니다.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "네트워크 격리가 필요한 경우 관리되는 vnet 옵션을 사용합니다.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6733,6 +6852,17 @@ "text": "관리형 vnet IR을 사용하여 Azure Integration Runtime에 대한 공용 인터넷을 통한 액세스 제한", "waf": "안전" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "관리형 프라이빗 엔드포인트는 Fabric Spark 워크로드의 데이터 소스에 대한 보안 및 비공개 액세스를 허용하는 기능입니다. 스타터 풀은 관리형 PE와 함께 사용할 수 없습니다", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "Azure 서비스에 액세스하도록 관리형 프라이빗 엔드포인트 구성", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6744,6 +6874,82 @@ "text": "관리형 Azure IR을 사용하여 리소스에 연결하도록 관리형 프라이빗 엔드포인트 구성", "waf": "안전" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric은 가상 네트워크의 개인 IP 주소를 사용합니다. 엔드포인트를 사용하면 네트워크의 사용자가 개인 링크를 사용하여 개인 IP 주소를 통해 Fabric과 통신할 수 있습니다.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "자신의 Azure vnet의 리소스(예: Fabric 환경에서 들어오는 트래픽)에 액세스하도록 Private Links 구성", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "사용자 인증 시점은 IP 주소, 위치 및 관리 중인 디바이스를 포함할 수 있는 정책 집합에 따라 결정됩니다.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "사용자가 패브릭 환경에 액세스하려는 경우 Microsoft Entra ID 조건부 액세스를 구성합니다", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure에서 서비스 태그는 네트워크 보안 규칙에 대한 업데이트 또는 변경의 복잡성을 최소화하기 위해 자동으로 그룹으로 관리되는 정의된 IP 주소 그룹입니다.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "Azure 서비스 태그를 사용하여 Microsoft 패브릭과의 연결을 사용하도록 설정할 수 있습니다.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "선택적", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "Fabric URL을 허용 목록에 추가할 수 있습니다", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "선택적", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "허용 목록에 Power BI URL을 추가할 수 있습니다", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "안전" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "데이터 게이트웨이를 사용하면 Azure 및 기타 데이터 서비스를 Microsoft Fabric 및 Power Platform에 연결하여 데이터 원본과 안전하게 통신하고, 쿼리를 실행하고, 결과를 서비스로 다시 전송할 수 있습니다.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "보통", + "text": "온-프레미스 데이터 게이트웨이 또는 Vnet 데이터 게이트웨이를 구성하고 사용하여 온-프레미스 또는 가상 네트워크 뒤의 소스에 연결합니다.", + "waf": "안전" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure Private Link를 사용하면 프라이빗 엔드포인트를 통해 Azure의 다양한 PaaS(Platform as a Service) 배포에 연결할 수 있습니다. 프라이빗 엔드포인트는 특정 가상 네트워크 및 서브넷 내의 개인 IP 주소입니다", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", + "severity": "보통", + "text": "고객 Vnet 및 데이터 팩터리의 원본에 연결하도록 Private Links 구성", + "waf": "안전" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6785,6 +6991,28 @@ "text": "Azure Key Vault에 암호, 비밀 저장Store passwords, secrets in Azure Key Vault", "waf": "안전" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Azure Key Vault에 자격 증명 또는 비밀 값을 저장하고 파이프라인 실행 중에 사용하여 활동에 전달할 수 있습니다.", + "guid": "6f4a1652-bddd-4ea8-a487-cdec4861bc3b", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "보통", + "text": "파이프라인 활동에서 Azure Key Vault 비밀 사용Use Azure Key Vault secrets in pipeline activities", + "waf": "안전" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "자체 호스팅 통합 런타임이 있는 컴퓨터에서 온-프레미스 데이터 저장소(중요한 정보가 있는 연결된 서비스)에 대한 자격 증명을 암호화하고 저장할 수 있습니다.", + "guid": "c14aeb7e-66e8-4d9a-9bec-218e6436b173", + "link": "https://learn.microsoft.com/azure/data-factory/encrypt-credentials-self-hosted-integration-runtime", + "service": "Azure Data Factory", + "severity": "보통", + "text": "Azure Data Factory에서 SHIR 데이터 저장소를 사용하여 온-프레미스에 대한 자격 증명 암호화", + "waf": "안전" + }, { "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "guid": "6db55f57-9603-4334-adf9-cc23418db612", @@ -7049,6 +7277,17 @@ "text": "클러스터 생성 권한을 제한합니다.", "waf": "안전" }, + { + "arm-service": "Microsoft.Databricks/workspaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "계정 관리자는 RestrictWorkspaceAdmins라는 작업 영역 설정을 구성하여 작업 영역 관리자가 작업 소유자를 자신으로만 변경하고 작업 실행 설정을 서비스 주체 사용자 역할이 있는 서비스 주체로 제한할 수 있습니다.", + "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", + "severity": "높다", + "text": "작업 영역 관리자 제한", + "waf": "안전" + }, { "arm-service": "Microsoft.Databricks/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -7540,1854 +7779,2286 @@ "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", "service": "App Services", "severity": "보통", - "text": "유효성이 검사된 코드 배포", + "text": "유효성이 검사된 코드 배포", + "waf": "안전" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "지원되는 플랫폼, 프로그래밍 언어, 프로토콜 및 프레임워크의 최신 버전을 사용합니다.", + "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", + "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", + "service": "App Services", + "severity": "높다", + "text": "최신 플랫폼, 언어, 프로토콜 및 프레임워크 사용", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "ab5351f6-383a-45ed-9c5e-b143b16db40a", + "link": "https://learn.microsoft.com/azure/aks/use-windows-hpc", + "service": "AKS", + "severity": "낮다", + "text": "AKS Windows 워크로드에 필요한 경우 HostProcess 컨테이너를 사용할 수 있습니다.", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "a280dcf5-90ce-465d-b8e1-3f9ccbd46926", + "link": "https://learn.microsoft.com/azure/azure-functions/functions-kubernetes-keda", + "service": "AKS", + "severity": "낮다", + "text": "이벤트 기반 워크로드를 실행하는 경우 KEDA 사용Use KEDA if running event-driven workloads", + "waf": "공연" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", + "link": "https://dapr.io/", + "service": "AKS", + "severity": "낮다", + "text": "Dapr을 사용하여 마이크로 서비스 개발 용이", + "waf": "작업" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (sku.tier=='Paid') | distinct id,compliant", + "guid": "71d41e36-10cc-457b-9a4b-1410d4395898", + "link": "https://learn.microsoft.com/azure/aks/uptime-sla", + "service": "AKS", + "severity": "높다", + "text": "SLA 지원 AKS 제품 사용", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "c1288b3c-6a57-4cfc-9444-51e1a3d3453a", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", + "service": "AKS", + "severity": "낮다", + "text": "Pod 및 배포 정의에서 중단 예산 사용Use Disruption Budgets in your pod and deployment definitions", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure AKS Review", + "guid": "3c763963-7a55-42d5-a15e-401955387e5c", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", + "service": "ACR", + "severity": "높다", + "text": "개인 레지스트리를 사용하는 경우 여러 지역에 이미지를 저장하도록 지역 복제를 구성합니다", + "waf": "신뢰도" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "f82cb8eb-8c0a-4a63-a25a-4956eaa8dc4a", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/aks/eslz-cost-governance-with-kubecost", + "service": "AKS", + "severity": "낮다", + "text": "kubecost와 같은 외부 애플리케이션을 사용하여 다른 사용자에게 비용 할당", + "waf": "비용" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "4d3dfbab-9924-4831-a68d-fdf0d72f462c", + "link": "https://learn.microsoft.com/azure/aks/scale-down-mode", + "service": "AKS", + "severity": "낮다", + "text": "축소 모드를 사용하여 노드 삭제/할당 취소", + "waf": "비용" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "87e651ea-bc4a-4a87-a6df-c06a4b570ebc", + "link": "https://learn.microsoft.com/azure/aks/gpu-multi-instance", + "service": "AKS", + "severity": "보통", + "text": "필요한 경우 AKS 클러스터에서 다중 인스턴스 분할 GPU 사용", + "waf": "비용" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "2b72a08b-0410-4cd6-9093-e068a5cf27e8", + "link": "https://learn.microsoft.com/azure/aks/start-stop-nodepools", + "service": "AKS", + "severity": "낮다", + "text": "개발/테스트 클러스터를 실행하는 경우 NodePool 시작/중지를 사용합니다.", + "waf": "비용" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.azurepolicy) and properties.addonProfiles.azurepolicy.enabled==true) | distinct id,compliant", + "guid": "9ca48e4a-85e2-4223-bce8-bb12307ca5f1", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes", + "service": "AKS", + "severity": "보통", + "text": "Kubernetes용 Azure Policy를 사용하여 클러스터 규정 준수 보장", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | project id,name,resourceGroup,poolcount=array_length(pools) | extend compliant = (poolcount > 1)", + "guid": "6f158e3e-a3a9-42c2-be7e-2165c3a87af4", + "link": "https://learn.microsoft.com/azure/aks/use-system-pools", + "service": "AKS", + "severity": "보통", + "text": "사용자/시스템 노드 풀이 있는 컨트롤 플레인에서 응용 프로그램 분리", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "a7a1f893-9bda-4477-98f2-4c116775c2ea", + "link": "https://learn.microsoft.com/azure/aks/use-system-pools", + "service": "AKS", + "severity": "낮다", + "text": "시스템 nodepool에 taint를 추가하여 전용으로 만듭니다.", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "55b46a94-8008-4ae7-b7e4-b475b6c8bdbf", + "link": "https://learn.microsoft.com/azure/container-registry/", + "service": "AKS", + "severity": "보통", + "text": "이미지에 개인 레지스트리(예: ACR) 사용", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure AKS Review", + "guid": "59bce65d-e8a0-43f9-9879-468d66a786d6", + "link": "https://learn.microsoft.com/azure/security-center/container-security", + "service": "ACR", + "severity": "보통", + "text": "이미지에서 취약성 검사", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "d167dd18-2b0a-4c24-8b99-9a646f8389a7", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-cluster-isolation", + "service": "AKS", + "severity": "높다", + "text": "앱 분리 요구 사항 정의(네임스페이스/노드 풀/클러스터)", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "5e3df584-eccc-4d97-a3b6-bcda3b50eb2e", + "link": "https://github.com/Azure/secrets-store-csi-driver-provider-azure", + "service": "AKS", + "severity": "보통", + "text": "CSI 비밀 저장소 드라이버를 사용하여 Azure Key Vault에 비밀 저장", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "b03dda6d-58d7-4c89-8ddb-107d5769ae66", + "link": "https://learn.microsoft.com/azure/aks/update-credentials", + "service": "AKS", + "severity": "높다", + "text": "클러스터에 서비스 주체를 사용하는 경우 주기적으로(예: 분기별) 자격 증명을 새로 고칩니다", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "e7ba73a3-0508-4f80-806f-527db30cee96", + "link": "https://learn.microsoft.com/azure/aks/use-kms-etcd-encryption", + "service": "AKS", + "severity": "보통", + "text": "필요한 경우 키 관리 서비스 etcd 암호화를 추가합니다.", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "ec8e4e42-0344-41b0-b865-9123e8956d31", + "link": "https://learn.microsoft.com/azure/confidential-computing/confidential-nodes-aks-overview", + "service": "AKS", + "severity": "낮다", + "text": "필요한 경우 AKS용 기밀 컴퓨팅을 사용하는 것이 좋습니다.", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "c9e95ffe-6dd1-4a17-8c5f-110389ca9b21", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-enable", + "service": "AKS", + "severity": "보통", + "text": "컨테이너용 Defender 사용 고려", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.servicePrincipalProfile.clientId=='msi') | distinct id,compliant", + "guid": "ed127dd1-42b0-46b2-8c69-99a646f3389a", + "link": "https://learn.microsoft.com/azure/aks/use-managed-identity", + "service": "AKS", + "severity": "높다", + "text": "서비스 주체 대신 관리 ID 사용", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.aadProfile) | distinct id,compliant", + "guid": "7e42c78e-78c0-46a6-8a21-94956e698dc4", + "link": "https://learn.microsoft.com/azure/aks/managed-aad", + "service": "AKS", + "severity": "보통", + "text": "AAD와 인증 통합(관리형 통합 사용)", + "waf": "안전" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "a2fe27b2-e287-401a-8352-beedf79b488d", + "link": "https://learn.microsoft.com/azure/aks/control-kubeconfig-access", + "service": "AKS", + "severity": "보통", + "text": "관리자 kubeconfig에 대한 액세스 제한(get-credentials --admin)", "waf": "안전" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "지원되는 플랫폼, 프로그래밍 언어, 프로토콜 및 프레임워크의 최신 버전을 사용합니다.", - "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", - "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", - "service": "App Services", - "severity": "높다", - "text": "최신 플랫폼, 언어, 프로토콜 및 프레임워크 사용", + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "eec4962c-c3bd-421b-b77f-26e5e6b3bec3", + "link": "https://learn.microsoft.com/azure/aks/manage-azure-rbac", + "service": "AKS", + "severity": "보통", + "text": "AAD RBAC와 권한 부여 통합", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "ab5351f6-383a-45ed-9c5e-b143b16db40a", - "link": "https://learn.microsoft.com/azure/aks/use-windows-hpc", + "guid": "d4f3537c-1346-4dc5-9027-a71ffe1bd05d", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-identity", "service": "AKS", - "severity": "낮다", - "text": "AKS Windows 워크로드에 필요한 경우 HostProcess 컨테이너를 사용할 수 있습니다.", - "waf": "신뢰도" + "severity": "높다", + "text": "쿠버네티스에서 RBAC 권한을 제한하기 위해 네임스페이스 사용", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "a280dcf5-90ce-465d-b8e1-3f9ccbd46926", - "link": "https://learn.microsoft.com/azure/azure-functions/functions-kubernetes-keda", + "guid": "d2e0d5d7-71d4-41e3-910c-c57b4a4b1410", + "link": "https://learn.microsoft.com/azure/aks/workload-identity-migration-sidecar", "service": "AKS", - "severity": "낮다", - "text": "이벤트 기반 워크로드를 실행하는 경우 KEDA 사용Use KEDA if running event-driven workloads", - "waf": "공연" + "severity": "보통", + "text": "Pod ID 액세스 관리의 경우 Azure AD 워크로드 ID(미리 보기)를 사용합니다.", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", - "link": "https://dapr.io/", + "guid": "f4dcf690-1b30-407d-abab-6f8aa780d3a3", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#non-interactive-sign-in-with-kubelogin", "service": "AKS", - "severity": "낮다", - "text": "Dapr을 사용하여 마이크로 서비스 개발 용이", - "waf": "작업" + "severity": "보통", + "text": "AKS 비대화형 로그인의 경우 kubelogin(미리 보기)을 사용합니다.", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (sku.tier=='Paid') | distinct id,compliant", - "guid": "71d41e36-10cc-457b-9a4b-1410d4395898", - "link": "https://learn.microsoft.com/azure/aks/uptime-sla", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.disableLocalAccounts==true) | distinct id,compliant", + "guid": "b085b1f2-3119-4771-8c9a-bbf4411810ec", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#disable-local-accounts", "service": "AKS", - "severity": "높다", - "text": "SLA 지원 AKS 제품 사용", - "waf": "신뢰도" + "severity": "보통", + "text": "AKS 로컬 계정 사용 안 함", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "c1288b3c-6a57-4cfc-9444-51e1a3d3453a", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", + "guid": "36abb0db-c118-4f4c-9880-3f30f9a2deb6", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#configure-just-in-time-cluster-access-with-azure-ad-and-aks", "service": "AKS", "severity": "낮다", - "text": "Pod 및 배포 정의에서 중단 예산 사용Use Disruption Budgets in your pod and deployment definitions", - "waf": "신뢰도" + "text": "필요한 경우 Just-in-time 클러스터 액세스 구성", + "waf": "안전" }, { - "arm-service": "microsoft.containerregistry/registries", + "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "3c763963-7a55-42d5-a15e-401955387e5c", - "link": "https://learn.microsoft.com/azure/container-registry/container-registry-geo-replication", - "service": "ACR", - "severity": "높다", - "text": "개인 레지스트리를 사용하는 경우 여러 지역에 이미지를 저장하도록 지역 복제를 구성합니다", - "waf": "신뢰도" + "guid": "c4d7f4c6-79bf-45d0-aa05-ce8fc717e150", + "link": "https://learn.microsoft.com/azure/aks/managed-aad#use-conditional-access-with-azure-ad-and-aks", + "service": "AKS", + "severity": "낮다", + "text": "AKS에 필요한 경우 AAD 조건부 액세스 구성", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "f82cb8eb-8c0a-4a63-a25a-4956eaa8dc4a", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/aks/eslz-cost-governance-with-kubecost", + "guid": "e1123a7c-a333-4eb4-a120-4ee3f293c9f3", + "link": "https://learn.microsoft.com/azure/aks/use-group-managed-service-accounts", "service": "AKS", "severity": "낮다", - "text": "kubecost와 같은 외부 애플리케이션을 사용하여 다른 사용자에게 비용 할당", - "waf": "비용" + "text": "Windows AKS 워크로드에 필요한 경우 gMSA를 구성합니다. ", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "4d3dfbab-9924-4831-a68d-fdf0d72f462c", - "link": "https://learn.microsoft.com/azure/aks/scale-down-mode", + "guid": "1f711a74-3672-470b-b8b8-a2148d640d79", + "link": "https://learn.microsoft.com/azure/aks/use-managed-identity#use-a-pre-created-kubelet-managed-identity", "service": "AKS", - "severity": "낮다", - "text": "축소 모드를 사용하여 노드 삭제/할당 취소", - "waf": "비용" + "severity": "보통", + "text": "더 세밀하게 제어하려면 관리형 Kubelet ID를 사용하는 것이 좋습니다.", + "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "87e651ea-bc4a-4a87-a6df-c06a4b570ebc", - "link": "https://learn.microsoft.com/azure/aks/gpu-multi-instance", + "guid": "cbd8ac2a-aebc-4a2a-94da-1dbf3dc99248", + "link": "https://azure.github.io/application-gateway-kubernetes-ingress/setup/install-existing/", "service": "AKS", "severity": "보통", - "text": "필요한 경우 AKS 클러스터에서 다중 인스턴스 분할 GPU 사용", - "waf": "비용" + "text": "AGIC를 사용하는 경우 클러스터 간에 AppGW를 공유하지 마세요", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "2b72a08b-0410-4cd6-9093-e068a5cf27e8", - "link": "https://learn.microsoft.com/azure/aks/start-stop-nodepools", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnull(properties.addonProfiles.httpApplicationRouting) or properties.addonProfiles.httpApplicationRouting.enabled==false) | distinct id,compliant", + "guid": "8008ae7d-7e4b-4475-a6c8-bdbf59bce65d", + "link": "https://learn.microsoft.com/azure/aks/http-application-routing", "service": "AKS", - "severity": "낮다", - "text": "개발/테스트 클러스터를 실행하는 경우 NodePool 시작/중지를 사용합니다.", - "waf": "비용" + "severity": "높다", + "text": "AKS HTTP 라우팅 추가 기능을 사용하지 말고, 애플리케이션 라우팅 추가 기능과 함께 관리되는 NGINX 수신을 대신 사용합니다.", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.azurepolicy) and properties.addonProfiles.azurepolicy.enabled==true) | distinct id,compliant", - "guid": "9ca48e4a-85e2-4223-bce8-bb12307ca5f1", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/policy-for-kubernetes", + "guid": "7bacd7b9-c025-4a9d-a5d2-25d6bc5439d9", + "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", "service": "AKS", "severity": "보통", - "text": "Kubernetes용 Azure Policy를 사용하여 클러스터 규정 준수 보장", - "waf": "안전" + "text": "Windows 워크로드의 경우 가속화된 네트워킹을 사용합니다.", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | project id,name,resourceGroup,poolcount=array_length(pools) | extend compliant = (poolcount > 1)", - "guid": "6f158e3e-a3a9-42c2-be7e-2165c3a87af4", - "link": "https://learn.microsoft.com/azure/aks/use-system-pools", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (tolower(properties.networkProfile.loadBalancerSku)=='standard') | distinct id,compliant", + "guid": "ba7da7be-9952-4914-a384-5d997cb39132", + "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", "service": "AKS", - "severity": "보통", - "text": "사용자/시스템 노드 풀이 있는 컨트롤 플레인에서 응용 프로그램 분리", - "waf": "안전" + "severity": "높다", + "text": "표준 ALB 사용(기본 ALB와 반대)", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "a7a1f893-9bda-4477-98f2-4c116775c2ea", - "link": "https://learn.microsoft.com/azure/aks/use-system-pools", + "guid": "22fbe8d6-9b40-47ef-9011-25bb1a555a6b", + "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-node-pool-with-a-unique-subnet", "service": "AKS", - "severity": "낮다", - "text": "시스템 nodepool에 taint를 추가하여 전용으로 만듭니다.", + "severity": "보통", + "text": "Azure CNI를 사용하는 경우 NodePools에 다른 서브넷을 사용하는 것이 좋습니다.", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "55b46a94-8008-4ae7-b7e4-b475b6c8bdbf", - "link": "https://learn.microsoft.com/azure/container-registry/", + "guid": "c3c39c98-6bb2-4c12-859a-114b5e3df584", + "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", "service": "AKS", "severity": "보통", - "text": "이미지에 개인 레지스트리(예: ACR) 사용", + "text": "프라이빗 엔드포인트(기본 설정) 또는 Virtual Network 서비스 엔드포인트를 사용하여 클러스터에서 PaaS 서비스에 액세스", "waf": "안전" }, { - "arm-service": "microsoft.containerregistry/registries", + "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "59bce65d-e8a0-43f9-9879-468d66a786d6", - "link": "https://learn.microsoft.com/azure/security-center/container-security", - "service": "ACR", - "severity": "보통", - "text": "이미지에서 취약성 검사", - "waf": "안전" + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.networkPlugin=='azure') | distinct id,compliant", + "guid": "a0f61565-9de5-458f-a372-49c831112dbd", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "service": "AKS", + "severity": "높다", + "text": "요구 사항에 가장 적합한 CNI 네트워크 플러그 인 선택(Azure CNI 권장)", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "d167dd18-2b0a-4c24-8b99-9a646f8389a7", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-cluster-isolation", + "guid": "7faf12e7-0943-4f63-8472-2da29c2b1cd6", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "service": "AKS", "severity": "높다", - "text": "앱 분리 요구 사항 정의(네임스페이스/노드 풀/클러스터)", - "waf": "안전" + "text": "Azure CNI를 사용하는 경우 노드당 최대 Pod 수를 고려하여 서브넷 크기를 적절하게 조정합니다", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "5e3df584-eccc-4d97-a3b6-bcda3b50eb2e", - "link": "https://github.com/Azure/secrets-store-csi-driver-provider-azure", + "guid": "22f54b29-bade-43aa-b1e8-c38ec9366673", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "service": "AKS", - "severity": "보통", - "text": "CSI 비밀 저장소 드라이버를 사용하여 Azure Key Vault에 비밀 저장", + "severity": "높다", + "text": "Azure CNI를 사용하는 경우 최대 Pod/노드(기본값 30)를 확인합니다.", + "waf": "공연" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "description": "내부 앱의 경우 조직은 방화벽에서 전체 AKS 서브넷을 여는 경우가 많습니다. 이렇게 하면 노드에 대한 네트워크 액세스도 열리고 잠재적으로 Pod에 대한 액세스도 열립니다(Azure CNI를 사용하는 경우). LoadBalancer IP가 다른 서브넷에 있는 경우 앱 클라이언트에서 이 IP만 사용할 수 있어야 합니다. 또 다른 이유는 AKS 서브넷의 IP 주소가 부족한 리소스인 경우 서비스에 해당 IP 주소를 사용하면 클러스터의 최대 확장성이 감소하기 때문입니다.", + "guid": "13c00567-4b1e-4945-a459-c373e7ed6162", + "link": "https://learn.microsoft.com/azure/aks/internal-lb", + "service": "AKS", + "severity": "낮다", + "text": "개인 IP LoadBalancer 서비스를 사용하는 경우 AKS 서브넷이 아닌 전용 서브넷을 사용합니다", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "b03dda6d-58d7-4c89-8ddb-107d5769ae66", - "link": "https://learn.microsoft.com/azure/aks/update-credentials", + "guid": "43f63047-22d9-429c-8b1c-d622f54b29ba", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "service": "AKS", "severity": "높다", - "text": "클러스터에 서비스 주체를 사용하는 경우 주기적으로(예: 분기별) 자격 증명을 새로 고칩니다", - "waf": "안전" + "text": "그에 따라 서비스 IP 주소 범위의 크기를 조정합니다(클러스터 확장성이 제한됨).", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "e7ba73a3-0508-4f80-806f-527db30cee96", - "link": "https://learn.microsoft.com/azure/aks/use-kms-etcd-encryption", + "guid": "57bf217f-6dc8-481c-81e2-785773e9c00f", + "link": "https://learn.microsoft.com/azure/aks/use-byo-cni", "service": "AKS", - "severity": "보통", - "text": "필요한 경우 키 관리 서비스 etcd 암호화를 추가합니다.", + "severity": "낮다", + "text": "필요한 경우 자체 CNI 플러그인을 추가합니다.", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "ec8e4e42-0344-41b0-b865-9123e8956d31", - "link": "https://learn.microsoft.com/azure/confidential-computing/confidential-nodes-aks-overview", + "guid": "4b3bb365-9458-44d9-9ed1-5c8f52890364", + "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#assign-a-public-ip-per-node-for-your-node-pools", "service": "AKS", "severity": "낮다", - "text": "필요한 경우 AKS용 기밀 컴퓨팅을 사용하는 것이 좋습니다.", - "waf": "안전" + "text": "필요한 경우 AKS에서 노드당 공용 IP 구성", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "c9e95ffe-6dd1-4a17-8c5f-110389ca9b21", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-enable", + "guid": "b3808b9f-a1cf-4204-ad01-3a923ce474db", + "link": "https://learn.microsoft.com/azure/aks/concepts-network", "service": "AKS", "severity": "보통", - "text": "컨테이너용 Defender 사용 고려", - "waf": "안전" + "text": "수신 컨트롤러를 사용하여 LoadBalancer 유형 서비스를 사용하여 노출하는 대신 웹 기반 앱을 노출합니다", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.servicePrincipalProfile.clientId=='msi') | distinct id,compliant", - "guid": "ed127dd1-42b0-46b2-8c69-99a646f3389a", - "link": "https://learn.microsoft.com/azure/aks/use-managed-identity", + "guid": "ccb534e7-416e-4a1d-8e93-533b53199085", + "link": "https://learn.microsoft.com/azure/aks/nat-gateway", "service": "AKS", - "severity": "높다", - "text": "서비스 주체 대신 관리 ID 사용", - "waf": "안전" + "severity": "낮다", + "text": "송신 트래픽 크기 조정을 위해 Azure NAT Gateway를 outboundType으로 사용", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.aadProfile) | distinct id,compliant", - "guid": "7e42c78e-78c0-46a6-8a21-94956e698dc4", - "link": "https://learn.microsoft.com/azure/aks/managed-aad", + "guid": "8ee9a69a-1b58-4b1e-9c61-476e110a160b", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni#dynamic-allocation-of-ips-and-enhanced-subnet-support", "service": "AKS", "severity": "보통", - "text": "AAD와 인증 통합(관리형 통합 사용)", - "waf": "안전" + "text": "Azure CNI IP 소모를 방지하기 위해 IP의 동적 할당 사용", + "waf": "신뢰도" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "a2fe27b2-e287-401a-8352-beedf79b488d", - "link": "https://learn.microsoft.com/azure/aks/control-kubeconfig-access", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.outboundType=='userDefinedRouting') | distinct id,compliant", + "guid": "3b365a91-7ecb-4e48-bbe5-4cd7df2e8bba", + "link": "https://learn.microsoft.com/azure/aks/limit-egress-traffic", "service": "AKS", - "severity": "보통", - "text": "관리자 kubeconfig에 대한 액세스 제한(get-credentials --admin)", + "severity": "높다", + "text": "보안 요구 사항에 필요한 경우 AzFW/NVA를 사용하여 송신 트래픽 필터링", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "eec4962c-c3bd-421b-b77f-26e5e6b3bec3", - "link": "https://learn.microsoft.com/azure/aks/manage-azure-rbac", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = ((isnull(properties.apiServerAccessProfile.enablePrivateCluster) or properties.apiServerAccessProfile.enablePrivateCluster==false) and isnotnull(properties.apiServerAccessProfile.authorizedIPRanges)) | distinct id,compliant", + "guid": "c4581559-bb91-463e-a908-aed8c44ce3b2", + "link": "https://learn.microsoft.com/azure/aks/api-server-authorized-ip-ranges", "service": "AKS", "severity": "보통", - "text": "AAD RBAC와 권한 부여 통합", + "text": "퍼블릭 API 엔드포인트를 사용하는 경우 액세스할 수 있는 IP 주소를 제한합니다", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "d4f3537c-1346-4dc5-9027-a71ffe1bd05d", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-identity", + "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", + "guid": "ecccd979-3b6b-4cda-9b50-eb2eb03dda6d", + "link": "https://learn.microsoft.com/azure/aks/private-clusters", "service": "AKS", "severity": "높다", - "text": "쿠버네티스에서 RBAC 권한을 제한하기 위해 네임스페이스 사용", + "text": "요구 사항에 따라 개인 클러스터를 사용합니다", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "d2e0d5d7-71d4-41e3-910c-c57b4a4b1410", - "link": "https://learn.microsoft.com/azure/aks/workload-identity-migration-sidecar", + "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", + "guid": "ce7f2a7c-297c-47c6-adea-a6ff838db665", + "link": "https://learn.microsoft.com/azure/aks/use-network-policies", "service": "AKS", "severity": "보통", - "text": "Pod ID 액세스 관리의 경우 Azure AD 워크로드 ID(미리 보기)를 사용합니다.", + "text": "Windows 2019 및 2022 AKS 노드의 경우 Calico 네트워크 정책을 사용할 수 있습니다. ", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "f4dcf690-1b30-407d-abab-6f8aa780d3a3", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#non-interactive-sign-in-with-kubelogin", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.networkProfile.networkPolicy) | distinct id,compliant", + "guid": "58d7c892-ddb1-407d-9769-ae669ca48e4a", + "link": "https://learn.microsoft.com/azure/aks/use-network-policies", "service": "AKS", - "severity": "보통", - "text": "AKS 비대화형 로그인의 경우 kubelogin(미리 보기)을 사용합니다.", + "severity": "높다", + "text": "Kubernetes 네트워크 정책 옵션 사용(Calico/Azure)", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.disableLocalAccounts==true) | distinct id,compliant", - "guid": "b085b1f2-3119-4771-8c9a-bbf4411810ec", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#disable-local-accounts", + "guid": "85e2223e-ce8b-4b12-907c-a5f16f158e3e", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", "service": "AKS", - "severity": "보통", - "text": "AKS 로컬 계정 사용 안 함", + "severity": "높다", + "text": "쿠버네티스 네트워크 정책을 사용하여 클러스터 내 보안 강화", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "36abb0db-c118-4f4c-9880-3f30f9a2deb6", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#configure-just-in-time-cluster-access-with-azure-ad-and-aks", + "guid": "a3a92c2d-e7e2-4165-a3a8-7af4a7a1f893", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", "service": "AKS", - "severity": "낮다", - "text": "필요한 경우 Just-in-time 클러스터 액세스 구성", + "severity": "높다", + "text": "웹 워크로드(UI 또는 API)에 WAF 사용Use a WAF for web workloads (UIs or APIs)", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "c4d7f4c6-79bf-45d0-aa05-ce8fc717e150", - "link": "https://learn.microsoft.com/azure/aks/managed-aad#use-conditional-access-with-azure-ad-and-aks", + "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", + "guid": "9bda4776-8f24-4c11-9775-c2ea55b46a94", + "link": "https://learn.microsoft.com/azure/virtual-network/ddos-protection-overview", "service": "AKS", - "severity": "낮다", - "text": "AKS에 필요한 경우 AAD 조건부 액세스 구성", + "severity": "보통", + "text": "AKS Virtual Network에서 DDoS 표준 사용Use DDoS Standard in the AKS Virtual Network", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "e1123a7c-a333-4eb4-a120-4ee3f293c9f3", - "link": "https://learn.microsoft.com/azure/aks/use-group-managed-service-accounts", + "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", + "guid": "6c46b91a-1107-4485-ad66-3183e2a8c266", + "link": "https://learn.microsoft.com/azure/aks/http-proxy", "service": "AKS", "severity": "낮다", - "text": "Windows AKS 워크로드에 필요한 경우 gMSA를 구성합니다. ", + "text": "필요한 경우 회사 HTTP 프록시를 추가합니다.", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "1f711a74-3672-470b-b8b8-a2148d640d79", - "link": "https://learn.microsoft.com/azure/aks/use-managed-identity#use-a-pre-created-kubelet-managed-identity", + "guid": "e9855d04-c3c3-49c9-a6bb-2c12159a114b", + "link": "https://learn.microsoft.com/azure/aks/servicemesh-about", "service": "AKS", "severity": "보통", - "text": "더 세밀하게 제어하려면 관리형 Kubelet ID를 사용하는 것이 좋습니다.", + "text": "고급 마이크로서비스 통신 관리를 위해 서비스 메시를 사용하는 것이 좋습니다", "waf": "안전" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "cbd8ac2a-aebc-4a2a-94da-1dbf3dc99248", - "link": "https://azure.github.io/application-gateway-kubernetes-ingress/setup/install-existing/", + "guid": "67f7a9ed-5b31-4f38-a3f3-9812b2463cff", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-metric-alerts", "service": "AKS", - "severity": "보통", - "text": "AGIC를 사용하는 경우 클러스터 간에 AppGW를 공유하지 마세요", - "waf": "신뢰도" + "severity": "높다", + "text": "가장 중요한 메트릭에 대한 경고 구성(권장 사항은 Container Insights 참조)", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnull(properties.addonProfiles.httpApplicationRouting) or properties.addonProfiles.httpApplicationRouting.enabled==false) | distinct id,compliant", - "guid": "8008ae7d-7e4b-4475-a6c8-bdbf59bce65d", - "link": "https://learn.microsoft.com/azure/aks/http-application-routing", + "guid": "337453a3-cc63-4963-9a65-22ac19e80696", + "link": "https://learn.microsoft.com/azure/advisor/advisor-get-started", "service": "AKS", - "severity": "높다", - "text": "AKS HTTP 라우팅 추가 기능을 사용하지 말고, 애플리케이션 라우팅 추가 기능과 함께 관리되는 NGINX 수신을 대신 사용합니다.", - "waf": "신뢰도" + "severity": "낮다", + "text": "Azure Advisor에서 클러스터에 대한 권장 사항을 정기적으로 확인합니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "7bacd7b9-c025-4a9d-a5d2-25d6bc5439d9", - "link": "https://learn.microsoft.com/azure/virtual-network/accelerated-networking-overview", + "guid": "3aa70560-e7e7-4968-be3d-628af35b2ced", + "link": "https://learn.microsoft.com/azure/aks/certificate-rotation", "service": "AKS", - "severity": "보통", - "text": "Windows 워크로드의 경우 가속화된 네트워킹을 사용합니다.", - "waf": "공연" + "severity": "낮다", + "text": "AKS 자동 인증서 회전 사용", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (tolower(properties.networkProfile.loadBalancerSku)=='standard') | distinct id,compliant", - "guid": "ba7da7be-9952-4914-a384-5d997cb39132", - "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", + "guid": "e189c599-df0d-45a7-9dd4-ce32c1881370", + "link": "https://learn.microsoft.com/azure/aks/supported-kubernetes-versions", "service": "AKS", "severity": "높다", - "text": "표준 ALB 사용(기본 ALB와 반대)", - "waf": "신뢰도" + "text": "kubernetes 버전을 주기적으로(예: 분기별) 업그레이드하거나 AKS 자동 업그레이드 기능을 사용하는 정기적인 프로세스가 있습니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "22fbe8d6-9b40-47ef-9011-25bb1a555a6b", - "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#add-a-node-pool-with-a-unique-subnet", + "guid": "6f7c4c0d-4e51-4464-ad24-57ed67138b82", + "link": "https://learn.microsoft.com/azure/aks/node-updates-kured", "service": "AKS", - "severity": "보통", - "text": "Azure CNI를 사용하는 경우 NodePools에 다른 서브넷을 사용하는 것이 좋습니다.", - "waf": "안전" + "severity": "높다", + "text": "node-image upgrade를 사용하지 않는 경우 Linux 노드 업그레이드에 kured를 사용합니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "c3c39c98-6bb2-4c12-859a-114b5e3df584", - "link": "https://learn.microsoft.com/azure/private-link/private-link-overview", + "guid": "139c9580-ade3-426a-ba09-cf157d9f6477", + "link": "https://learn.microsoft.com/azure/aks/node-image-upgrade", "service": "AKS", - "severity": "보통", - "text": "프라이빗 엔드포인트(기본 설정) 또는 Virtual Network 서비스 엔드포인트를 사용하여 클러스터에서 PaaS 서비스에 액세스", - "waf": "안전" + "severity": "높다", + "text": "클러스터 노드 이미지를 주기적으로(예: 매주) 업그레이드하는 정기적인 프로세스가 있습니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.networkPlugin=='azure') | distinct id,compliant", - "guid": "a0f61565-9de5-458f-a372-49c831112dbd", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "guid": "0102ce16-ee30-41e6-b882-e52e4621dd68", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/bedrock/bedrock-automated-deployments", "service": "AKS", - "severity": "높다", - "text": "요구 사항에 가장 적합한 CNI 네트워크 플러그 인 선택(Azure CNI 권장)", - "waf": "신뢰도" + "severity": "낮다", + "text": "gitops를 고려하여 애플리케이션 또는 클러스터 구성을 여러 클러스터에 배포합니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "7faf12e7-0943-4f63-8472-2da29c2b1cd6", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", + "guid": "d7672c26-7602-4482-85a4-14527fbe855c", + "link": "https://learn.microsoft.com/azure/aks/command-invoke", "service": "AKS", - "severity": "높다", - "text": "Azure CNI를 사용하는 경우 노드당 최대 Pod 수를 고려하여 서브넷 크기를 적절하게 조정합니다", - "waf": "공연" + "severity": "낮다", + "text": "프라이빗 클러스터에서 AKS 명령 호출을 사용하는 것이 좋습니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "22f54b29-bade-43aa-b1e8-c38ec9366673", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", + "guid": "31d7aaab-7571-4449-ab80-53d89e89d17b", + "link": "https://learn.microsoft.com/azure/aks/node-auto-repair#node-autodrain", + "service": "AKS", + "severity": "낮다", + "text": "계획된 이벤트의 경우 노드 자동 드레인 사용을 고려하십시오.", + "waf": "작업" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "ed0fda7f-211b-47c7-8b6e-c18873fb473c", + "link": "https://learn.microsoft.com/azure/aks/faq", "service": "AKS", "severity": "높다", - "text": "Azure CNI를 사용하는 경우 최대 Pod/노드(기본값 30)를 확인합니다.", - "waf": "공연" + "text": "노드 RG(일명 '인프라 RG')의 운영자가 변경을 수행하지 않도록 자체 거버넌스 관행을 개발합니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "description": "내부 앱의 경우 조직은 방화벽에서 전체 AKS 서브넷을 여는 경우가 많습니다. 이렇게 하면 노드에 대한 네트워크 액세스도 열리고 잠재적으로 Pod에 대한 액세스도 열립니다(Azure CNI를 사용하는 경우). LoadBalancer IP가 다른 서브넷에 있는 경우 앱 클라이언트에서 이 IP만 사용할 수 있어야 합니다. 또 다른 이유는 AKS 서브넷의 IP 주소가 부족한 리소스인 경우 서비스에 해당 IP 주소를 사용하면 클러스터의 최대 확장성이 감소하기 때문입니다.", - "guid": "13c00567-4b1e-4945-a459-c373e7ed6162", - "link": "https://learn.microsoft.com/azure/aks/internal-lb", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.nodeResourceGroup !startswith 'MC_') | distinct id,compliant", + "guid": "73b32a5a-67f7-4a9e-b5b3-1f38c3f39812", + "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", "service": "AKS", "severity": "낮다", - "text": "개인 IP LoadBalancer 서비스를 사용하는 경우 AKS 서브넷이 아닌 전용 서브넷을 사용합니다", - "waf": "안전" + "text": "사용자 정의 노드 RG (일명 '인프라 RG') 이름 사용", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "43f63047-22d9-429c-8b1c-d622f54b29ba", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", + "guid": "b2463cff-e189-4c59-adf0-d5a73dd4ce32", + "link": "https://kubernetes.io/docs/setup/release/notes/", "service": "AKS", - "severity": "높다", - "text": "그에 따라 서비스 IP 주소 범위의 크기를 조정합니다(클러스터 확장성이 제한됨).", - "waf": "신뢰도" + "severity": "보통", + "text": "YAML 매니페스트에서 더 이상 사용되지 않는 Kubernetes API를 사용하지 마십시오.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "57bf217f-6dc8-481c-81e2-785773e9c00f", - "link": "https://learn.microsoft.com/azure/aks/use-byo-cni", + "guid": "c1881370-6f7c-44c0-b4e5-14648d2457ed", + "link": "https://learn.microsoft.com/azure-stack/aks-hci/adapt-apps-mixed-os-clusters", "service": "AKS", "severity": "낮다", - "text": "필요한 경우 자체 CNI 플러그인을 추가합니다.", - "waf": "안전" + "text": "테인트 Windows 노드", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "4b3bb365-9458-44d9-9ed1-5c8f52890364", - "link": "https://learn.microsoft.com/azure/aks/use-multiple-node-pools#assign-a-public-ip-per-node-for-your-node-pools", + "guid": "67138b82-0102-4ce1-9ee3-01e6e882e52e", + "link": "https://learn.microsoft.com/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-20H2%2Cwindows-10-20H2", "service": "AKS", "severity": "낮다", - "text": "필요한 경우 AKS에서 노드당 공용 IP 구성", - "waf": "공연" + "text": "Windows 컨테이너 패치 수준을 호스트 패치 수준과 동기화된 상태로 유지", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "b3808b9f-a1cf-4204-ad01-3a923ce474db", - "link": "https://learn.microsoft.com/azure/aks/concepts-network", + "description": "클러스터 수준의 진단 설정을 통해Via Diagnostic Settings at the cluster level", + "guid": "5b56ad48-408f-4e72-934c-476ba280dcf5", + "link": "https://learn.microsoft.com/azure/aks/monitor-aks", "service": "AKS", - "severity": "보통", - "text": "수신 컨트롤러를 사용하여 LoadBalancer 유형 서비스를 사용하여 노출하는 대신 웹 기반 앱을 노출합니다", - "waf": "신뢰도" + "severity": "낮다", + "text": "마스터 로그(즉, API 로그)를 Azure Monitor 또는 기본 로그 관리 솔루션으로 보냅니다", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "ccb534e7-416e-4a1d-8e93-533b53199085", - "link": "https://learn.microsoft.com/azure/aks/nat-gateway", + "guid": "64d1a846-e28a-4b6b-9a33-22a635c15a21", + "link": "https://learn.microsoft.com/azure/aks/node-pool-snapshot", "service": "AKS", "severity": "낮다", - "text": "송신 트래픽 크기 조정을 위해 Azure NAT Gateway를 outboundType으로 사용", - "waf": "신뢰도" + "text": "필요한 경우 nodePool 스냅샷을 사용합니다.", + "waf": "비용" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "8ee9a69a-1b58-4b1e-9c61-476e110a160b", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni#dynamic-allocation-of-ips-and-enhanced-subnet-support", + "guid": "c5a5b252-1e44-4a59-a9d2-399c4d7b68d0", + "link": "https://learn.microsoft.com/azure/aks/spot-node-pool", "service": "AKS", - "severity": "보통", - "text": "Azure CNI IP 소모를 방지하기 위해 IP의 동적 할당 사용", - "waf": "신뢰도" + "severity": "낮다", + "text": "시간에 민감하지 않은 워크로드에 대한 스폿 노드 풀 고려", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.networkProfile.outboundType=='userDefinedRouting') | distinct id,compliant", - "guid": "3b365a91-7ecb-4e48-bbe5-4cd7df2e8bba", - "link": "https://learn.microsoft.com/azure/aks/limit-egress-traffic", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.aciConnectorLinux) and properties.addonProfiles.aciConnectorLinux.enabled==true) | distinct id,compliant", + "guid": "c755562f-2b4e-4456-9b4d-874a748b662e", + "link": "https://learn.microsoft.com/azure/aks/concepts-scale", "service": "AKS", - "severity": "높다", - "text": "보안 요구 사항에 필요한 경우 AzFW/NVA를 사용하여 송신 트래픽 필터링", - "waf": "안전" + "severity": "낮다", + "text": "빠른 버스팅을 위해 AKS 가상 노드 고려", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = ((isnull(properties.apiServerAccessProfile.enablePrivateCluster) or properties.apiServerAccessProfile.enablePrivateCluster==false) and isnotnull(properties.apiServerAccessProfile.authorizedIPRanges)) | distinct id,compliant", - "guid": "c4581559-bb91-463e-a908-aed8c44ce3b2", - "link": "https://learn.microsoft.com/azure/aks/api-server-authorized-ip-ranges", - "service": "AKS", - "severity": "보통", - "text": "퍼블릭 API 엔드포인트를 사용하는 경우 액세스할 수 있는 IP 주소를 제한합니다", - "waf": "안전" + "guid": "6f8389a7-f82c-4b8e-a8c0-aa63a25a4956", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", + "service": "AKS", + "severity": "높다", + "text": "Container Insights(또는 Prometheus와 같은 다른 도구)를 사용하여 클러스터 지표 모니터링", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", - "guid": "ecccd979-3b6b-4cda-9b50-eb2eb03dda6d", - "link": "https://learn.microsoft.com/azure/aks/private-clusters", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.omsagent) and properties.addonProfiles.omsagent.enabled==true) | distinct id,compliant", + "guid": "eaa8dc4a-2436-47b3-9697-15b1752beee0", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", "service": "AKS", "severity": "높다", - "text": "요구 사항에 따라 개인 클러스터를 사용합니다", - "waf": "안전" + "text": "Container Insights(또는 Telegraf/ElasticSearch와 같은 다른 도구)를 사용하여 클러스터 로그를 저장하고 분석합니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | where isnotnull(properties.apiServerAccessProfile.enablePrivateCluster) | extend compliant = (properties.apiServerAccessProfile.enablePrivateCluster==true) | distinct id, compliant", - "guid": "ce7f2a7c-297c-47c6-adea-a6ff838db665", - "link": "https://learn.microsoft.com/azure/aks/use-network-policies", + "guid": "4621dd68-c5a5-4be2-bdb1-1726769ef669", + "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-analyze", "service": "AKS", "severity": "보통", - "text": "Windows 2019 및 2022 AKS 노드의 경우 Calico 네트워크 정책을 사용할 수 있습니다. ", - "waf": "안전" + "text": "노드의 CPU 및 메모리 사용률 모니터링", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = isnotnull(properties.networkProfile.networkPolicy) | distinct id,compliant", - "guid": "58d7c892-ddb1-407d-9769-ae669ca48e4a", - "link": "https://learn.microsoft.com/azure/aks/use-network-policies", + "guid": "1a4835ac-9422-423e-ae80-b123081a5417", + "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", "service": "AKS", - "severity": "높다", - "text": "Kubernetes 네트워크 정책 옵션 사용(Calico/Azure)", - "waf": "안전" + "severity": "보통", + "text": "Azure CNI를 사용하는 경우 노드당 사용되는 Pod IP의 %를 모니터링합니다.", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "85e2223e-ce8b-4b12-907c-a5f16f158e3e", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "description": "OS 디스크의 I/O는 중요한 리소스입니다. 노드의 OS가 I/O에서 제한되면 예측할 수 없는 동작이 발생할 수 있으며, 일반적으로 노드가 NotReady로 선언됩니다", + "guid": "415833ea-3ad3-4c2d-b733-165c3acbe04b", + "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance", "service": "AKS", - "severity": "높다", - "text": "쿠버네티스 네트워크 정책을 사용하여 클러스터 내 보안 강화", - "waf": "안전" + "severity": "보통", + "text": "노드에서 OS 디스크 큐 크기 모니터링Monitor OS disk queue depth in nodes", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "a3a92c2d-e7e2-4165-a3a8-7af4a7a1f893", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-network", + "guid": "be209d39-fda4-4777-a424-d116785c2fa5", + "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", "service": "AKS", - "severity": "높다", - "text": "웹 워크로드(UI 또는 API)에 WAF 사용Use a WAF for web workloads (UIs or APIs)", - "waf": "안전" + "severity": "보통", + "text": "AzFW/NVA에서 송신 필터링을 사용하지 않는 경우 표준 ALB 할당 SNAT 포트를 모니터링합니다", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", - "guid": "9bda4776-8f24-4c11-9775-c2ea55b46a94", - "link": "https://learn.microsoft.com/azure/virtual-network/ddos-protection-overview", + "guid": "74c2ee76-569b-4a79-a57e-dedf91b022c9", + "link": "https://learn.microsoft.com/azure/aks/aks-resource-health", "service": "AKS", "severity": "보통", - "text": "AKS Virtual Network에서 DDoS 표준 사용Use DDoS Standard in the AKS Virtual Network", - "waf": "안전" + "text": "AKS 클러스터에 대한 Resource Health 알림 구독Subscribe to resource health notifications for your AKS cluster", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "Resources | where type=~'microsoft.containerservice/managedclusters' | project resourceGroup,name,pools=properties.agentPoolProfiles | mv-expand pools | project subnetId=tostring(pools.vnetSubnetID) | where isnotempty(subnetId) | join (Resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,enableDdosProtection=tostring(properties.enableDdosProtection),subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,enableDdosProtection,subnetId=tostring(subnets.id)) on subnetId | distinct id,resourceGroup,name,enableDdosProtection | extend compliant = (enableDdosProtection == 'true')", - "guid": "6c46b91a-1107-4485-ad66-3183e2a8c266", - "link": "https://learn.microsoft.com/azure/aks/http-proxy", + "guid": "b54eb2eb-03dd-4aa3-9927-18e2edb11726", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "service": "AKS", - "severity": "낮다", - "text": "필요한 경우 회사 HTTP 프록시를 추가합니다.", - "waf": "안전" + "severity": "높다", + "text": "Pod 규격에서 요청 및 제한 구성", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "e9855d04-c3c3-49c9-a6bb-2c12159a114b", - "link": "https://learn.microsoft.com/azure/aks/servicemesh-about", + "guid": "769ef669-1a48-435a-a942-223ece80b123", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "service": "AKS", "severity": "보통", - "text": "고급 마이크로서비스 통신 관리를 위해 서비스 메시를 사용하는 것이 좋습니다", - "waf": "안전" + "text": "네임스페이스에 대한 리소스 할당량 적용Enforce resource quotas for namespaces", + "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "67f7a9ed-5b31-4f38-a3f3-9812b2463cff", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-metric-alerts", + "guid": "081a5417-4158-433e-a3ad-3c2de733165c", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", "service": "AKS", "severity": "높다", - "text": "가장 중요한 메트릭에 대한 경고 구성(권장 사항은 Container Insights 참조)", + "text": "구독에 노드 풀을 확장할 수 있는 충분한 할당량이 있는지 확인합니다.", "waf": "작업" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "337453a3-cc63-4963-9a65-22ac19e80696", - "link": "https://learn.microsoft.com/azure/advisor/advisor-get-started", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.autoScalerProfile)) | distinct id,compliant", + "guid": "90ce65de-8e13-4f9c-abd4-69266abca264", + "link": "https://learn.microsoft.com/azure/aks/concepts-scale", "service": "AKS", - "severity": "낮다", - "text": "Azure Advisor에서 클러스터에 대한 권장 사항을 정기적으로 확인합니다.", - "waf": "작업" + "severity": "보통", + "text": "Cluster Autoscaler 사용", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "3aa70560-e7e7-4968-be3d-628af35b2ced", - "link": "https://learn.microsoft.com/azure/aks/certificate-rotation", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.austoscalerProfile)) | distinct id,compliant", + "guid": "831c2872-c693-4b39-a887-a561bada49bc", + "link": "https://learn.microsoft.com/azure/aks/custom-node-configuration", "service": "AKS", "severity": "낮다", - "text": "AKS 자동 인증서 회전 사용", - "waf": "작업" + "text": "AKS 노드 풀에 대한 노드 구성 사용자 지정", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "e189c599-df0d-45a7-9dd4-ce32c1881370", - "link": "https://learn.microsoft.com/azure/aks/supported-kubernetes-versions", + "guid": "faa19bfe-9d55-4d04-a3c4-919ca1b2d121", + "link": "https://learn.microsoft.com/azure/aks/concepts-scale", "service": "AKS", - "severity": "높다", - "text": "kubernetes 버전을 주기적으로(예: 분기별) 업그레이드하거나 AKS 자동 업그레이드 기능을 사용하는 정기적인 프로세스가 있습니다.", - "waf": "작업" + "severity": "보통", + "text": "필요한 경우 Horizontal Pod Autoscaler 사용", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "6f7c4c0d-4e51-4464-ad24-57ed67138b82", - "link": "https://learn.microsoft.com/azure/aks/node-updates-kured", + "description": "노드가 클수록 임시 디스크 및 가속화된 네트워킹과 같은 더 높은 성능과 기능을 제공하지만 폭발 반경이 증가하고 크기 조정 세분성이 감소합니다", + "guid": "5ae124ba-34df-4585-bcdc-e9bd3bb0cdb3", + "link": "https://blog.cloudtrooper.net/2020/10/23/which-vm-size-should-i-choose-as-aks-node/", "service": "AKS", "severity": "높다", - "text": "node-image upgrade를 사용하지 않는 경우 Linux 노드 업그레이드에 kured를 사용합니다.", - "waf": "작업" + "text": "너무 크거나 너무 작지 않은 적절한 노드 크기를 고려합니다", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "139c9580-ade3-426a-ba09-cf157d9f6477", - "link": "https://learn.microsoft.com/azure/aks/node-image-upgrade", + "guid": "38800e6a-ae01-40a2-9fbc-ae5a06e5462d", + "link": "https://learn.microsoft.com/azure/aks/quotas-skus-regions#service-quotas-and-limits", "service": "AKS", - "severity": "높다", - "text": "클러스터 노드 이미지를 주기적으로(예: 매주) 업그레이드하는 정기적인 프로세스가 있습니다.", - "waf": "작업" + "severity": "낮다", + "text": "확장성을 위해 5,000개 이상의 노드가 필요한 경우 추가 AKS 클러스터를 사용하는 것이 좋습니다", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "0102ce16-ee30-41e6-b882-e52e4621dd68", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/bedrock/bedrock-automated-deployments", + "guid": "9583c0f6-6083-43f6-aa6b-df7102c901bb", + "link": "https://learn.microsoft.com/azure/event-grid/event-schema-aks", "service": "AKS", "severity": "낮다", - "text": "gitops를 고려하여 애플리케이션 또는 클러스터 구성을 여러 클러스터에 배포합니다.", - "waf": "작업" + "text": "AKS 자동화를 위해 EventGrid 이벤트를 구독하는 것이 좋습니다.", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "d7672c26-7602-4482-85a4-14527fbe855c", - "link": "https://learn.microsoft.com/azure/aks/command-invoke", + "guid": "c5016d8c-c6c9-4165-89ae-673ef0fff19d", + "link": "https://learn.microsoft.com/azure/aks/manage-abort-operations", "service": "AKS", "severity": "낮다", - "text": "프라이빗 클러스터에서 AKS 명령 호출을 사용하는 것이 좋습니다.", - "waf": "작업" + "text": "AKS 클러스터에서 장기 실행 작업의 경우 이벤트 종료를 고려합니다.", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "31d7aaab-7571-4449-ab80-53d89e89d17b", - "link": "https://learn.microsoft.com/azure/aks/node-auto-repair#node-autodrain", + "guid": "c4e37133-f186-4ce1-aed9-9f1b32f6e021", + "link": "https://learn.microsoft.com/azure/aks/use-azure-dedicated-hosts", "service": "AKS", "severity": "낮다", - "text": "계획된 이벤트의 경우 노드 자동 드레인 사용을 고려하십시오.", - "waf": "작업" + "text": "필요한 경우 AKS 노드에 Azure Dedicated Host를 사용하는 것이 좋습니다", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "ed0fda7f-211b-47c7-8b6e-c18873fb473c", - "link": "https://learn.microsoft.com/azure/aks/faq", + "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | mvexpand pools | extend compliant = (pools.osDiskType=='Ephemeral') | project id,name=strcat(name,'-',pools.name), resourceGroup, compliant", + "guid": "24367b33-6971-45b1-952b-eee0b9b588de", + "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", "service": "AKS", "severity": "높다", - "text": "노드 RG(일명 '인프라 RG')의 운영자가 변경을 수행하지 않도록 자체 거버넌스 관행을 개발합니다.", - "waf": "작업" + "text": "임시 OS 디스크 사용", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (properties.nodeResourceGroup !startswith 'MC_') | distinct id,compliant", - "guid": "73b32a5a-67f7-4a9e-b5b3-1f38c3f39812", - "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", + "guid": "f0ce315f-1120-4166-8206-94f2cf3a4d07", + "link": "https://learn.microsoft.com/azure/virtual-machines/disks-types", "service": "AKS", - "severity": "낮다", - "text": "사용자 정의 노드 RG (일명 '인프라 RG') 이름 사용", - "waf": "작업" + "severity": "높다", + "text": "임시 디스크가 아닌 디스크의 경우 여러 Pod를 실행하는 데 고성능이 필요하고 기본 AKS 로그 회전 임계값을 사용하여 대규모 로그를 생성하므로 많은 Pod/노드를 실행할 때 노드에 높은 IOPS 및 더 큰 OS 디스크를 사용합니다", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "b2463cff-e189-4c59-adf0-d5a73dd4ce32", - "link": "https://kubernetes.io/docs/setup/release/notes/", + "guid": "39c486ce-d5af-4062-89d5-18bb5fd795db", + "link": "https://learn.microsoft.com/azure/aks/use-ultra-disks", "service": "AKS", - "severity": "보통", - "text": "YAML 매니페스트에서 더 이상 사용되지 않는 Kubernetes API를 사용하지 마십시오.", - "waf": "작업" + "severity": "낮다", + "text": "고성능 스토리지 옵션의 경우 AKS에서 Ultra Disks를 사용합니다.", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "c1881370-6f7c-44c0-b4e5-14648d2457ed", - "link": "https://learn.microsoft.com/azure-stack/aks-hci/adapt-apps-mixed-os-clusters", + "guid": "9f7547c1-747d-4c56-868a-714435bd19dd", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-multi-region", "service": "AKS", - "severity": "낮다", - "text": "테인트 Windows 노드", - "waf": "작업" + "severity": "보통", + "text": "클러스터에서 상태를 유지하지 않고 외부(AzStorage, AzSQL, Cosmos 등)에 데이터를 저장합니다.", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "guid": "67138b82-0102-4ce1-9ee3-01e6e882e52e", - "link": "https://learn.microsoft.com/virtualization/windowscontainers/deploy-containers/version-compatibility?tabs=windows-server-20H2%2Cwindows-10-20H2", + "guid": "24429eb7-2281-4376-85cc-57b4a4b18142", + "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-storage", "service": "AKS", - "severity": "낮다", - "text": "Windows 컨테이너 패치 수준을 호스트 패치 수준과 동기화된 상태로 유지", - "waf": "작업" + "severity": "보통", + "text": "AzFiles 표준을 사용하는 경우 성능상의 이유로 AzFiles 프리미엄 및/또는 ANF를 고려합니다", + "waf": "공연" }, { "arm-service": "microsoft.containerservice/managedClusters", "checklist": "Azure AKS Review", - "description": "클러스터 수준의 진단 설정을 통해Via Diagnostic Settings at the cluster level", - "guid": "5b56ad48-408f-4e72-934c-476ba280dcf5", - "link": "https://learn.microsoft.com/azure/aks/monitor-aks", + "guid": "83958a8c-2689-4b32-ab57-cfc64546135a", + "link": "https://learn.microsoft.com/azure/aks/availability-zones#azure-disk-availability-zone-support", "service": "AKS", - "severity": "낮다", - "text": "마스터 로그(즉, API 로그)를 Azure Monitor 또는 기본 로그 관리 솔루션으로 보냅니다", - "waf": "작업" + "severity": "보통", + "text": "Azure 디스크 및 AZ를 사용하는 경우 올바른 영역에 스토리지를 프로비전하기 위해 VolumeBindingMode::WaitForFirstConsumer를 사용하여 LRS 디스크의 영역 내에 노드 풀을 사용하거나 여러 영역에 걸쳐 있는 노드 풀에 ZRS 디스크를 사용하는 것이 좋습니다", + "waf": "공연" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "4238f409-2ea0-43be-a06b-2a993c98aa7b", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", + "service": "Azure Functions", + "severity": "높다", + "text": "비즈니스 및 SLO 요구 사항에 따라 올바른 기능 호스팅 계획을 선택하십시오.", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "a9808100-d640-4f77-ac56-1ec0600f6752", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", + "service": "Azure Functions", + "severity": "높다", + "text": "지역적으로 적용 가능한 가용성 영역 활용(소비 계층에는 사용할 수 없음)", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "5969d03e-eacf-4042-b127-73c55e3575fa", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-functions?tabs=azure-portal#cross-region-disaster-recovery-and-business-continuity", + "service": "Azure Functions", + "severity": "보통", + "text": "중요한 워크로드에 대한 지역 간 DR 전략 고려", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "47a0aae0-d8a0-43b1-9791-e934dee3754c", + "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", + "service": "Azure Functions", + "severity": "높다", + "text": "격리된 환경에 배포하는 경우 ASE(App Service Environment) v3을 사용하거나 마이그레이션합니다", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "64d1a846-e28a-4b6b-9a33-22a635c15a21", - "link": "https://learn.microsoft.com/azure/aks/node-pool-snapshot", - "service": "AKS", - "severity": "낮다", - "text": "필요한 경우 nodePool 스냅샷을 사용합니다.", - "waf": "비용" + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "17232891-f89f-4eaa-90f1-3b34bf798ed5", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", + "service": "Azure Functions", + "severity": "높다", + "text": "App Service 계획에서 실행되는 모든 함수 앱에 대해 'Always On'이 사용하도록 설정되어 있는지 확인합니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "c5a5b252-1e44-4a59-a9d2-399c4d7b68d0", - "link": "https://learn.microsoft.com/azure/aks/spot-node-pool", - "service": "AKS", - "severity": "낮다", - "text": "시간에 민감하지 않은 워크로드에 대한 스폿 노드 풀 고려", - "waf": "작업" + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "40a325c2-7c0e-49e6-86d8-c273b4dc21ba", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations?tabs=azure-cli#shared-storage-accounts", + "service": "Azure Functions", + "severity": "보통", + "text": "함수 앱을 자체 스토리지 계정에 페어링합니다. 긴밀하게 결합되지 않는 한 함수 앱에 대한 스토리지 계정을 다시 사용하지 마세요", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.aciConnectorLinux) and properties.addonProfiles.aciConnectorLinux.enabled==true) | distinct id,compliant", - "guid": "c755562f-2b4e-4456-9b4d-874a748b662e", - "link": "https://learn.microsoft.com/azure/aks/concepts-scale", - "service": "AKS", - "severity": "낮다", - "text": "빠른 버스팅을 위해 AKS 가상 노드 고려", + "arm-service": "Microsoft.Web/sites", + "checklist": "Azure Function Review", + "guid": "bb42650c-257d-4cb0-822a-131138b8e6f0", + "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", + "service": "Azure Functions", + "severity": "보통", + "text": "Azure DevOps 또는 GitHub를 활용하여 CI/CD를 간소화하고 함수 앱 코드를 보호합니다.", "waf": "작업" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "6f8389a7-f82c-4b8e-a8c0-aa63a25a4956", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", - "service": "AKS", - "severity": "높다", - "text": "Container Insights(또는 Prometheus와 같은 다른 도구)를 사용하여 클러스터 지표 모니터링", - "waf": "작업" + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "6d8e32a8-3892-479d-a40b-10f6b4f6f298", + "link": "https://learn.microsoft.com/azure/spring-apps/concepts-blue-green-deployment-strategies", + "service": "Spring Apps", + "severity": "보통", + "text": "Azure Spring Apps는 모든 앱에 대해 두 개의 배포를 허용하며, 그 중 하나만 프로덕션 트래픽을 수신합니다. 블루-그린 배포 전략을 통해 가동 중지 시간 제로를 달성할 수 있습니다. 파란색 녹색 배포는 표준 및 엔터프라이즈 계층에서만 사용할 수 있습니다. ADO/GitHub 작업과 함께 CI/CD를 사용하여 배포를 자동화할 수 있습니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.addonProfiles.omsagent) and properties.addonProfiles.omsagent.enabled==true) | distinct id,compliant", - "guid": "eaa8dc4a-2436-47b3-9697-15b1752beee0", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/container-insights-overview", - "service": "AKS", - "severity": "높다", - "text": "Container Insights(또는 Telegraf/ElasticSearch와 같은 다른 도구)를 사용하여 클러스터 로그를 저장하고 분석합니다.", - "waf": "작업" + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "fbcb40ac-9480-4a6d-bcf4-8081252a6716", + "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", + "service": "Spring Apps", + "severity": "보통", + "text": "Azure Spring Apps 인스턴스는 애플리케이션에 대해 여러 지역에서 만들 수 있으며 Traffic Manager/Front Door에서 트래픽을 라우팅할 수 있습니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "4621dd68-c5a5-4be2-bdb1-1726769ef669", - "link": "https://learn.microsoft.com/azure/azure-monitor/containers/container-insights-analyze", - "service": "AKS", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "ff1ae6a7-9301-4feb-9d11-56cd72f1d4ef", + "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", + "service": "Spring Apps", "severity": "보통", - "text": "노드의 CPU 및 메모리 사용률 모니터링", - "waf": "작업" + "text": "지원되는 지역에서 Azure Spring Apps는 영역 중복으로 배포할 수 있으며, 이는 인스턴스가 가용성 영역에 자동으로 분산됨을 의미합니다. 이 기능은 Standard 및 Enterprise 계층에서만 사용할 수 있습니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "1a4835ac-9422-423e-ae80-b123081a5417", - "link": "https://learn.microsoft.com/azure/aks/configure-azure-cni", - "service": "AKS", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "ffc735ad-fbb1-4802-b43f-ad6387c4c066", + "link": "https://learn.microsoft.com/azure/spring-apps/concept-understand-app-and-deployment", + "service": "Spring Apps", "severity": "보통", - "text": "Azure CNI를 사용하는 경우 노드당 사용되는 Pod IP의 %를 모니터링합니다.", - "waf": "작업" + "text": "앱에 1개 이상의 앱 인스턴스 사용", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "description": "OS 디스크의 I/O는 중요한 리소스입니다. 노드의 OS가 I/O에서 제한되면 예측할 수 없는 동작이 발생할 수 있으며, 일반적으로 노드가 NotReady로 선언됩니다", - "guid": "415833ea-3ad3-4c2d-b733-165c3acbe04b", - "link": "https://learn.microsoft.com/azure/virtual-machines/premium-storage-performance", - "service": "AKS", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "7504c230-6035-4183-95a5-85762acc6075", + "link": "https://learn.microsoft.com/azure/spring-apps/diagnostic-services", + "service": "Spring Apps", "severity": "보통", - "text": "노드에서 OS 디스크 큐 크기 모니터링Monitor OS disk queue depth in nodes", - "waf": "작업" + "text": "로그, 메트릭 및 추적을 사용하여 Azure Spring Apps를 모니터링합니다. ASA를 Application Insights와 통합하고, 오류를 추적하고, 통합 문서를 만듭니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "be209d39-fda4-4777-a424-d116785c2fa5", - "link": "https://learn.microsoft.com/azure/aks/load-balancer-standard", - "service": "AKS", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "1eb48d58-3eec-4ef5-80b0-d2b0dde3f0c6", + "link": "https://learn.microsoft.com/azure/spring-apps/how-to-configure-enterprise-spring-cloud-gateway", + "service": "Spring Apps", "severity": "보통", - "text": "AzFW/NVA에서 송신 필터링을 사용하지 않는 경우 표준 ALB 할당 SNAT 포트를 모니터링합니다", - "waf": "작업" + "text": "Spring Cloud Gateway에서 자동 크기 조정 설정", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "74c2ee76-569b-4a79-a57e-dedf91b022c9", - "link": "https://learn.microsoft.com/azure/aks/aks-resource-health", - "service": "AKS", - "severity": "보통", - "text": "AKS 클러스터에 대한 Resource Health 알림 구독Subscribe to resource health notifications for your AKS cluster", - "waf": "작업" + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "97411607-b6fd-4335-99d1-9885faf4e392", + "link": "https://learn.microsoft.com/azure/spring-apps/how-to-setup-autoscale", + "service": "Spring Apps", + "severity": "낮다", + "text": "표준 소비 및 전용 플랜이 있는 앱에 대해 자동 크기 조정을 사용하도록 설정합니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "b54eb2eb-03dd-4aa3-9927-18e2edb11726", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", - "service": "AKS", - "severity": "높다", - "text": "Pod 규격에서 요청 및 제한 구성", - "waf": "작업" + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "dfcaffd1-d27c-4ef2-998d-64c1df3a7ac3", + "link": "https://learn.microsoft.com/azure/spring-apps/overview", + "service": "Spring Apps", + "severity": "보통", + "text": "중요 업무용 앱에 대한 Spring Boot의 상업적 지원을 위해 Enterprise 플랜을 사용합니다. 다른 계층에서는 OSS 지원을 받을 수 있습니다.", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "769ef669-1a48-435a-a942-223ece80b123", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Azure Data Factory Review Checklist", + "guid": "ab91932c-9fc9-4d1b-a881-37f5e6c0cb9e", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-ADF_v1.docx", + "service": "Azure Data Factory", "severity": "보통", - "text": "네임스페이스에 대한 리소스 할당량 적용Enforce resource quotas for namespaces", - "waf": "작업" + "text": "Azure Data Factory에 대한 FTA 복원력 플레이북 활용", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "081a5417-4158-433e-a3ad-3c2de733165c", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Azure Data Factory Review Checklist", + "guid": "e503547c-d447-4e82-9138-a7200f1cac6d", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/analytics/pipelines-disaster-recovery", + "service": "Azure Data Factory", "severity": "높다", - "text": "구독에 노드 풀을 확장할 수 있는 충분한 할당량이 있는지 확인합니다.", - "waf": "작업" + "text": "가용성 영역을 지원하는 지역에서 영역 중복 파이프라인 사용Use zone redundant pipelines in regions that support Availability Zones", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.autoScalerProfile)) | distinct id,compliant", - "guid": "90ce65de-8e13-4f9c-abd4-69266abca264", - "link": "https://learn.microsoft.com/azure/aks/concepts-scale", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Azure Data Factory Review Checklist", + "guid": "9ef1d6e8-32e5-42e3-911c-818b1a0bc511", + "link": "https://learn.microsoft.com/azure/data-factory/source-control", + "service": "Azure Data Factory", "severity": "보통", - "text": "Cluster Autoscaler 사용", - "waf": "공연" + "text": "DevOps를 사용하여 Github/Azure DevOps 통합으로 ARM 템플릿 백업 ", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (isnotnull(properties.austoscalerProfile)) | distinct id,compliant", - "guid": "831c2872-c693-4b39-a887-a561bada49bc", - "link": "https://learn.microsoft.com/azure/aks/custom-node-configuration", - "service": "AKS", - "severity": "낮다", - "text": "AKS 노드 풀에 대한 노드 구성 사용자 지정", - "waf": "공연" + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Azure Data Factory Review Checklist", + "guid": "e43a18a9-cd29-49cf-b7b1-7db8255562f2", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/analytics/pipelines-disaster-recovery", + "service": "Azure Data Factory", + "severity": "보통", + "text": "다른 지역에서 자체 호스팅 통합 런타임 VM을 복제해야 합니다. ", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "faa19bfe-9d55-4d04-a3c4-919ca1b2d121", - "link": "https://learn.microsoft.com/azure/aks/concepts-scale", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Azure Data Factory Review Checklist", + "guid": "aee4563a-fd83-4393-98b2-62d6dc5f512a", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/analytics/pipelines-disaster-recovery", + "service": "Azure Data Factory", "severity": "보통", - "text": "필요한 경우 Horizontal Pod Autoscaler 사용", - "waf": "공연" + "text": "자매 지역에서 네트워크를 복제하거나 복제해야 합니다. 다른 지역에서 Vnet의 복사본을 만들어야 합니다", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Azure Data Factory Review Checklist", + "description": "ADF 파이프라인에서 Key Vault를 사용하는 경우 Key Vault를 복제하기 위해 아무 작업도 수행할 필요가 없습니다. Key Vault는 관리되는 서비스이며 Microsoft에서 처리합니다", + "guid": "25498f6d-bad3-47da-a43b-c6ce1d7aa9b2", + "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", + "service": "Azure Data Factory", + "severity": "낮다", + "text": "Keyvault 통합을 사용하는 경우 Keyvault의 SLA를 사용하여 가용성을 파악합니다", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "description": "노드가 클수록 임시 디스크 및 가속화된 네트워킹과 같은 더 높은 성능과 기능을 제공하지만 폭발 반경이 증가하고 크기 조정 세분성이 감소합니다", - "guid": "5ae124ba-34df-4585-bcdc-e9bd3bb0cdb3", - "link": "https://blog.cloudtrooper.net/2020/10/23/which-vm-size-should-i-choose-as-aks-node/", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "65285269-440c-44be-9d3e-0844276d4bdc", + "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/pass-foudations-playbooks-ADB_v1.docx", + "service": "Azure Data Factory", "severity": "높다", - "text": "너무 크거나 너무 작지 않은 적절한 노드 크기를 고려합니다", - "waf": "공연" + "text": "Databricks HA/DR 플레이북 참조", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "38800e6a-ae01-40a2-9fbc-ae5a06e5462d", - "link": "https://learn.microsoft.com/azure/aks/quotas-skus-regions#service-quotas-and-limits", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "a0e6c465-89d5-458b-a37d-3974d1112dbd", + "link": "https://github.com/databrickslabs/databricks-sync", + "service": "Azure Data Factory", "severity": "낮다", - "text": "확장성을 위해 5,000개 이상의 노드가 필요한 경우 추가 AKS 클러스터를 사용하는 것이 좋습니다", - "waf": "공연" + "text": "Databricks Sync 사용", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "9583c0f6-6083-43f6-aa6b-df7102c901bb", - "link": "https://learn.microsoft.com/azure/event-grid/event-schema-aks", - "service": "AKS", - "severity": "낮다", - "text": "AKS 자동화를 위해 EventGrid 이벤트를 구독하는 것이 좋습니다.", - "waf": "공연" + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "89d558b9-37d3-4974-b111-2dbd7aaf12e6", + "link": "https://learn.microsoft.com/azure/databricks/security/secrets/secret-scopes", + "service": "Azure Data Factory", + "severity": "보통", + "text": "ARM 템플릿 및 비밀 범위를 포함한 작업 영역 구성 백업Backup your workspace configuration including ARM templates and secret scopes", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "c5016d8c-c6c9-4165-89ae-673ef0fff19d", - "link": "https://learn.microsoft.com/azure/aks/manage-abort-operations", - "service": "AKS", - "severity": "낮다", - "text": "AKS 클러스터에서 장기 실행 작업의 경우 이벤트 종료를 고려합니다.", - "waf": "공연" + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "b94ee5ef-47d2-4d92-a81b-1cd6d1f54b29", + "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/sharing-metadata-across-different-databricks-workspaces-using/ba-p/3679757", + "service": "Azure Data Factory", + "severity": "보통", + "text": "Hive 외부 메타스토어를 사용하여 여러 Databricks 작업 영역에서 메타데이터 공유", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "c4e37133-f186-4ce1-aed9-9f1b32f6e021", - "link": "https://learn.microsoft.com/azure/aks/use-azure-dedicated-hosts", - "service": "AKS", - "severity": "낮다", - "text": "필요한 경우 AKS 노드에 Azure Dedicated Host를 사용하는 것이 좋습니다", - "waf": "공연" + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "769e3969-0e78-428a-a936-657d03b0f466", + "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/disaster-recovery-strategy-in-azure-databricks-using-the-hive/ba-p/3684581", + "service": "Azure Data Factory", + "severity": "보통", + "text": "Hive 외부 메타스토어를 사용하여 Databricks에서 재해 복구 전략 계획", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | project id,resourceGroup,name,pools=properties.agentPoolProfiles | mvexpand pools | extend compliant = (pools.osDiskType=='Ephemeral') | project id,name=strcat(name,'-',pools.name), resourceGroup, compliant", - "guid": "24367b33-6971-45b1-952b-eee0b9b588de", - "link": "https://learn.microsoft.com/azure/aks/cluster-configuration", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "4b1d944a-3598-437e-b79d-6c6d3a364a5b", + "link": "https://www.databricks.com/blog/2021/04/20/attack-of-the-delta-clones-against-disaster-recovery-availability-complexity.html", + "service": "Azure Data Factory", + "severity": "보통", + "text": "깊고 얕은 클론으로 데이터 백업", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "description": "RAGRS 스토리지 계정의 보조 엔드포인트를 사용하여 Blob 다운로드Download the blob using the secondary endpoint in RAGRS storage account", + "guid": "7abae48a-bd54-4cd7-ae2e-86768357c559", + "link": "https://techcommunity.microsoft.com/t5/azure-paas-blog/download-the-blob-using-secondary-endpoint-in-ragrs-storage/ba-p/2403750", + "service": "Azure Data Factory", + "severity": "보통", + "text": "Azure Storage RA-GRS에 데이터 백업", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "675c5ee8-5b85-49c7-944c-e3b1a28b875a", + "link": "https://learn.microsoft.com/azure/databricks/dev-tools/index-ci-cd", + "service": "Azure Data Factory", "severity": "높다", - "text": "임시 OS 디스크 사용", - "waf": "공연" + "text": "DevOps를 사용하여 코드 백업", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "f0ce315f-1120-4166-8206-94f2cf3a4d07", - "link": "https://learn.microsoft.com/azure/virtual-machines/disks-types", - "service": "AKS", + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "guid": "a1bf1038-9f03-4a4d-8ce4-63dbbbc8682a", + "link": "https://learn.microsoft.com/azure/databricks/administration-guide/disaster-recovery", + "service": "Azure Data Factory", "severity": "높다", - "text": "임시 디스크가 아닌 디스크의 경우 여러 Pod를 실행하는 데 고성능이 필요하고 기본 AKS 로그 회전 임계값을 사용하여 대규모 로그를 생성하므로 많은 Pod/노드를 실행할 때 노드에 높은 IOPS 및 더 큰 OS 디스크를 사용합니다", - "waf": "공연" + "text": "액티브/액티브 또는 액티브/패시브 구성을 사용한 재해 복구 계획Plan for Disaster recovery using Active/Active or Active/Passive Configuration", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "39c486ce-d5af-4062-89d5-18bb5fd795db", - "link": "https://learn.microsoft.com/azure/aks/use-ultra-disks", - "service": "AKS", - "severity": "낮다", - "text": "고성능 스토리지 옵션의 경우 AKS에서 Ultra Disks를 사용합니다.", - "waf": "공연" + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "DataBricks Review Checklist", + "description": "백업 및/또는 다른 Databricks 작업 영역으로 마이그레이션하기 위해 모든 Databricks 리소스를 기록하는 마이그레이션 패키지", + "guid": "5abc92a4-eda1-4dae-8cc8-5c47c6b781cc", + "link": "https://github.com/databrickslabs/migrate", + "service": "Azure Data Factory", + "severity": "보통", + "text": "Databricks 마이그레이션 도구 사용", + "waf": "신뢰도" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "9f7547c1-747d-4c56-868a-714435bd19dd", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-multi-region", - "service": "AKS", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "d7941d4a-7b6f-458f-8714-2f8f8c059ad4", + "link": "https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies", + "service": "APIM", "severity": "보통", - "text": "클러스터에서 상태를 유지하지 않고 외부(AzStorage, AzSQL, Cosmos 등)에 데이터를 저장합니다.", - "waf": "공연" + "text": "전역 수준에서 오류 처리 정책 구현", + "waf": "작업" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "24429eb7-2281-4376-85cc-57b4a4b18142", - "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-storage", - "service": "AKS", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "0b0c0765-ff37-4369-90bd-3eb23ce71b08", + "link": "https://learn.microsoft.com/azure/api-management/set-edit-policies?tabs=form#use-base-element-to-set-policy-evaluation-order", + "service": "APIM", "severity": "보통", - "text": "AzFiles 표준을 사용하는 경우 성능상의 이유로 AzFiles 프리미엄 및/또는 ANF를 고려합니다", - "waf": "공연" + "text": "모든 API 정책에 요소가 포함되어 있는지 확인합니다.", + "waf": "작업" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "83958a8c-2689-4b32-ab57-cfc64546135a", - "link": "https://learn.microsoft.com/azure/aks/availability-zones#azure-disk-availability-zone-support", - "service": "AKS", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", + "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", + "service": "APIM", "severity": "보통", - "text": "Azure 디스크 및 AZ를 사용하는 경우 올바른 영역에 스토리지를 프로비전하기 위해 VolumeBindingMode::WaitForFirstConsumer를 사용하여 LRS 디스크의 영역 내에 노드 풀을 사용하거나 여러 영역에 걸쳐 있는 노드 풀에 ZRS 디스크를 사용하는 것이 좋습니다", - "waf": "공연" + "text": "정책 조각을 사용하여 여러 API에서 동일한 정책 정의를 반복하지 않도록 합니다.", + "waf": "작업" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "4238f409-2ea0-43be-a06b-2a993c98aa7b", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", - "service": "Azure Functions", - "severity": "높다", - "text": "비즈니스 및 SLO 요구 사항에 따라 올바른 기능 호스팅 계획을 선택하십시오.", - "waf": "신뢰도" + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", + "link": "https://learn.microsoft.com/azure/api-management/monetization-support", + "service": "APIM", + "severity": "보통", + "text": "API로 수익을 창출할 계획이라면 '수익 창출 지원' 도움말에서 권장사항을 확인하세요", + "waf": "작업" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "a9808100-d640-4f77-ac56-1ec0600f6752", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/functions-scale#overview-of-plans", - "service": "Azure Functions", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "a7d0840a-c8c4-4e83-adec-5ca578eb4049", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor#resource-logs", + "service": "APIM", "severity": "높다", - "text": "지역적으로 적용 가능한 가용성 영역 활용(소비 계층에는 사용할 수 없음)", - "waf": "신뢰도" + "text": "진단 설정을 사용하도록 설정하여 로그를 Azure Monitor로 내보내기", + "waf": "작업" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "5969d03e-eacf-4042-b127-73c55e3575fa", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-functions?tabs=azure-portal#cross-region-disaster-recovery-and-business-continuity", - "service": "Azure Functions", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "8691fa38-45ed-4299-a247-fecd98d35deb", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-app-insights", + "service": "APIM", "severity": "보통", - "text": "중요한 워크로드에 대한 지역 간 DR 전략 고려", - "waf": "신뢰도" + "text": "더 자세한 원격 분석을 위해 Application Insights 사용", + "waf": "작업" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "47a0aae0-d8a0-43b1-9791-e934dee3754c", - "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", - "service": "Azure Functions", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "55fd27bb-76ac-4a91-bc37-049e885be6b7", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor", + "service": "APIM", "severity": "높다", - "text": "격리된 환경에 배포하는 경우 ASE(App Service Environment) v3을 사용하거나 마이그레이션합니다", - "waf": "신뢰도" + "text": "가장 중요한 메트릭에 대한 경고 구성", + "waf": "작업" + }, + { + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "39460bdb-156f-4dc2-a87f-1e8c11ab0998", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#certificate-management-in-azure-key-vault", + "service": "APIM", + "severity": "높다", + "text": "사용자 지정 SSL 인증서가 안전하게 액세스하고 업데이트할 수 있도록 Azure Key Vault에 저장되어 있는지 확인합니다", + "waf": "안전" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "17232891-f89f-4eaa-90f1-3b34bf798ed5", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", - "service": "Azure Functions", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "e9217997-5f6c-479d-8576-8f2adf706ec8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-ad-authentication-required-for-data-plane-access", + "service": "APIM", "severity": "높다", - "text": "App Service 계획에서 실행되는 모든 함수 앱에 대해 'Always On'이 사용하도록 설정되어 있는지 확인합니다.", - "waf": "신뢰도" + "text": "Azure AD를 사용하여 API(데이터 평면)에 들어오는 요청 보호", + "waf": "안전" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "40a325c2-7c0e-49e6-86d8-c273b4dc21ba", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/storage-considerations?tabs=azure-cli#shared-storage-accounts", - "service": "Azure Functions", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "5e5f64ba-c90e-480e-8888-398d96cf0bfb", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-aad", + "service": "APIM", "severity": "보통", - "text": "함수 앱을 자체 스토리지 계정에 페어링합니다. 긴밀하게 결합되지 않는 한 함수 앱에 대한 스토리지 계정을 다시 사용하지 마세요", - "waf": "신뢰도" + "text": "Microsoft Entra ID를 사용하여 개발자 포털에서 사용자 인증", + "waf": "안전" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Azure Function Review", - "guid": "bb42650c-257d-4cb0-822a-131138b8e6f0", - "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", - "service": "Azure Functions", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "f8e574ce-280f-49c8-b2ef-68279b081cf3", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-create-groups", + "service": "APIM", "severity": "보통", - "text": "Azure DevOps 또는 GitHub를 활용하여 CI/CD를 간소화하고 함수 앱 코드를 보호합니다.", - "waf": "작업" + "text": "제품의 가시성을 제어하기 위해 적절한 그룹을 만듭니다", + "waf": "안전" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "6d8e32a8-3892-479d-a40b-10f6b4f6f298", - "link": "https://learn.microsoft.com/azure/spring-apps/concepts-blue-green-deployment-strategies", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "06862505-2d9a-4874-9491-2837b00a3475", + "link": "https://learn.microsoft.com/azure/api-management/backends", + "service": "APIM", "severity": "보통", - "text": "Azure Spring Apps는 모든 앱에 대해 두 개의 배포를 허용하며, 그 중 하나만 프로덕션 트래픽을 수신합니다. 블루-그린 배포 전략을 통해 가동 중지 시간 제로를 달성할 수 있습니다. 파란색 녹색 배포는 표준 및 엔터프라이즈 계층에서만 사용할 수 있습니다. ADO/GitHub 작업과 함께 CI/CD를 사용하여 배포를 자동화할 수 있습니다.", - "waf": "신뢰도" + "text": "백엔드 기능을 사용하여 중복 API 백엔드 구성 제거", + "waf": "작업" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "fbcb40ac-9480-4a6d-bcf4-8081252a6716", - "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "03b125d5-b69b-4739-b7fd-84b86da4933e", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-properties?tabs=azure-portal", + "service": "APIM", "severity": "보통", - "text": "Azure Spring Apps 인스턴스는 애플리케이션에 대해 여러 지역에서 만들 수 있으며 Traffic Manager/Front Door에서 트래픽을 라우팅할 수 있습니다.", - "waf": "신뢰도" + "text": "명명된 값을 사용하여 정책에서 사용할 수 있는 공통 값 저장", + "waf": "작업" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "ff1ae6a7-9301-4feb-9d11-56cd72f1d4ef", - "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "beae759e-4ddb-4326-bf26-47f87d3454b6", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", + "service": "APIM", "severity": "보통", - "text": "지원되는 지역에서 Azure Spring Apps는 영역 중복으로 배포할 수 있으며, 이는 인스턴스가 가용성 영역에 자동으로 분산됨을 의미합니다. 이 기능은 Standard 및 Enterprise 계층에서만 사용할 수 있습니다.", + "text": "DR의 경우 99.99% SLA를 위해 둘 이상의 지역에 걸쳐 확장된 배포와 함께 프리미엄 계층을 활용합니다", "waf": "신뢰도" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "ffc735ad-fbb1-4802-b43f-ad6387c4c066", - "link": "https://learn.microsoft.com/azure/spring-apps/concept-understand-app-and-deployment", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", + "link": "https://learn.microsoft.com/azure/api-management/high-availability", + "service": "APIM", "severity": "보통", - "text": "앱에 1개 이상의 앱 인스턴스 사용", + "text": "99.99%의 SLA 증가를 위해 둘 이상의 가용성 영역에 하나 이상의 단위를 배포합니다.", "waf": "신뢰도" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "7504c230-6035-4183-95a5-85762acc6075", - "link": "https://learn.microsoft.com/azure/spring-apps/diagnostic-services", - "service": "Spring Apps", - "severity": "보통", - "text": "로그, 메트릭 및 추적을 사용하여 Azure Spring Apps를 모니터링합니다. ASA를 Application Insights와 통합하고, 오류를 추적하고, 통합 문서를 만듭니다.", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "8d2db6e8-85c6-4118-a52c-ae76a4f27934", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#service-native-backup-capability", + "service": "APIM", + "severity": "높다", + "text": "자동화된 백업 루틴이 있는지 확인", "waf": "신뢰도" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "1eb48d58-3eec-4ef5-80b0-d2b0dde3f0c6", - "link": "https://learn.microsoft.com/azure/spring-apps/how-to-configure-enterprise-spring-cloud-gateway", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "43e60b94-7bca-43a2-aadf-efb04d63a485", + "link": "https://learn.microsoft.com/azure/api-management/retry-policy", + "service": "APIM", "severity": "보통", - "text": "Spring Cloud Gateway에서 자동 크기 조정 설정", + "text": "정책을 사용하여 장애 조치 백엔드 URL 및 캐싱을 추가하여 실패한 호출을 줄입니다.", "waf": "신뢰도" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "97411607-b6fd-4335-99d1-9885faf4e392", - "link": "https://learn.microsoft.com/azure/spring-apps/how-to-setup-autoscale", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "8210699f-8d43-45c2-8f19-57e54134bd8f", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-log-event-hubs", + "service": "APIM", "severity": "낮다", - "text": "표준 소비 및 전용 플랜이 있는 앱에 대해 자동 크기 조정을 사용하도록 설정합니다.", - "waf": "신뢰도" + "text": "고성능 수준에서 기록해야 하는 경우 Event Hubs 정책을 고려합니다", + "waf": "작업" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "dfcaffd1-d27c-4ef2-998d-64c1df3a7ac3", - "link": "https://learn.microsoft.com/azure/spring-apps/overview", - "service": "Spring Apps", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "121bfc39-fa7b-4096-b93b-ab56c1bc0bed", + "link": "https://learn.microsoft.com/azure/api-management/api-management-sample-flexible-throttling", + "service": "APIM", "severity": "보통", - "text": "중요 업무용 앱에 대한 Spring Boot의 상업적 지원을 위해 Enterprise 플랜을 사용합니다. 다른 계층에서는 OSS 지원을 받을 수 있습니다.", - "waf": "신뢰도" + "text": "제한 정책을 적용하여 초당 요청 수 제어Apply throttling policies to control the number of requests per second", + "training": "https://learn.microsoft.com/training/modules/protect-apis-on-api-management/", + "waf": "공연" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "Azure Data Factory Review Checklist", - "guid": "ab91932c-9fc9-4d1b-a881-37f5e6c0cb9e", - "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/paas-foundations-playbooks-ADF_v1.docx", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "bb5f356b-3daf-47a2-a9ee-867a8100bbd5", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-autoscale", + "service": "APIM", "severity": "보통", - "text": "Azure Data Factory에 대한 FTA 복원력 플레이북 활용", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "Azure Data Factory Review Checklist", - "guid": "e503547c-d447-4e82-9138-a7200f1cac6d", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/analytics/pipelines-disaster-recovery", - "service": "Azure Data Factory", - "severity": "높다", - "text": "가용성 영역을 지원하는 지역에서 영역 중복 파이프라인 사용Use zone redundant pipelines in regions that support Availability Zones", - "waf": "신뢰도" + "text": "부하가 증가할 때 인스턴스 수를 확장하도록 자동 크기 조정 구성Configure autoscaling to scale out the number of instances when the load increases", + "waf": "공연" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "Azure Data Factory Review Checklist", - "guid": "9ef1d6e8-32e5-42e3-911c-818b1a0bc511", - "link": "https://learn.microsoft.com/azure/data-factory/source-control", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "84b94abb-59b6-4b9d-8587-3413669468e8", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-provision-self-hosted-gateway", + "service": "APIM", "severity": "보통", - "text": "DevOps를 사용하여 Github/Azure DevOps 통합으로 ARM 템플릿 백업 ", - "waf": "신뢰도" + "text": "Azure에 백 엔드 API에 가까운 지역이 없는 자체 호스팅 게이트웨이를 배포합니다.", + "waf": "공연" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "Azure Data Factory Review Checklist", - "guid": "e43a18a9-cd29-49cf-b7b1-7db8255562f2", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/analytics/pipelines-disaster-recovery", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "1fe8db45-a017-4888-8c4d-4422583cfae0", + "link": "https://learn.microsoft.com/azure/api-management/upgrade-and-scale#upgrade-and-scale", + "service": "APIM", "severity": "보통", - "text": "다른 지역에서 자체 호스팅 통합 런타임 VM을 복제해야 합니다. ", + "text": "프로덕션 워크로드에 프리미엄 계층을 사용합니다.", "waf": "신뢰도" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "Azure Data Factory Review Checklist", - "guid": "aee4563a-fd83-4393-98b2-62d6dc5f512a", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/analytics/pipelines-disaster-recovery", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "1b8d68a4-66cd-44d5-ba94-3ee94440e8d6", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region#-route-api-calls-to-regional-backend-services", + "service": "APIM", "severity": "보통", - "text": "자매 지역에서 네트워크를 복제하거나 복제해야 합니다. 다른 지역에서 Vnet의 복사본을 만들어야 합니다", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "Azure Data Factory Review Checklist", - "description": "ADF 파이프라인에서 Key Vault를 사용하는 경우 Key Vault를 복제하기 위해 아무 작업도 수행할 필요가 없습니다. Key Vault는 관리되는 서비스이며 Microsoft에서 처리합니다", - "guid": "25498f6d-bad3-47da-a43b-c6ce1d7aa9b2", - "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", - "service": "Azure Data Factory", - "severity": "낮다", - "text": "Keyvault 통합을 사용하는 경우 Keyvault의 SLA를 사용하여 가용성을 파악합니다", + "text": "다중 리전 모델에서는 Policies를 사용하여 가용성 또는 지연 시간에 따라 리전 백엔드로 요청을 라우팅합니다.", "waf": "신뢰도" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "65285269-440c-44be-9d3e-0844276d4bdc", - "link": "https://github.com/Azure/fta-resiliencyplaybooks/blob/main/pass-foudations-playbooks-ADB_v1.docx", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "46f07d33-ef9a-44e8-8f98-67c097c5d8cd", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#api-management-limits", + "service": "APIM", "severity": "높다", - "text": "Databricks HA/DR 플레이북 참조", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "a0e6c465-89d5-458b-a37d-3974d1112dbd", - "link": "https://github.com/databrickslabs/databricks-sync", - "service": "Azure Data Factory", - "severity": "낮다", - "text": "Databricks Sync 사용", + "text": "APIM의 제한에 유의해야 합니다.", "waf": "신뢰도" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "89d558b9-37d3-4974-b111-2dbd7aaf12e6", - "link": "https://learn.microsoft.com/azure/databricks/security/secrets/secret-scopes", - "service": "Azure Data Factory", - "severity": "보통", - "text": "ARM 템플릿 및 비밀 범위를 포함한 작업 영역 구성 백업Backup your workspace configuration including ARM templates and secret scopes", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "10f58602-f0f9-4d77-972a-956f6e0f2600", + "link": "https://learn.microsoft.com/en-us/azure/api-management/self-hosted-gateway-overview", + "service": "APIM", + "severity": "높다", + "text": "자체 호스팅 게이트웨이 배포가 복원력이 있는지 확인합니다.", "waf": "신뢰도" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "b94ee5ef-47d2-4d92-a81b-1cd6d1f54b29", - "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/sharing-metadata-across-different-databricks-workspaces-using/ba-p/3679757", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "7519e385-a88b-4d34-966b-6269d686e890", + "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", + "service": "APIM", "severity": "보통", - "text": "Hive 외부 메타스토어를 사용하여 여러 Databricks 작업 영역에서 메타데이터 공유", - "waf": "신뢰도" + "text": "다중 지역 배포를 위해 APIM 앞에서 Azure Front Door 사용Use Azure Front Door in front of APIM for multi-region deployment", + "waf": "공연" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "769e3969-0e78-428a-a936-657d03b0f466", - "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/disaster-recovery-strategy-in-azure-databricks-using-the-hive/ba-p/3684581", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "cd45c90e-7690-4753-930b-bf290c69c074", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#virtual-network-integration", + "service": "APIM", "severity": "보통", - "text": "Hive 외부 메타스토어를 사용하여 Databricks에서 재해 복구 전략 계획", - "waf": "신뢰도" + "text": "VNet(Virtual Network) 내에 서비스 배포Deploy the service within a Virtual Network (VNet)", + "waf": "안전" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "4b1d944a-3598-437e-b79d-6c6d3a364a5b", - "link": "https://www.databricks.com/blog/2021/04/20/attack-of-the-delta-clones-against-disaster-recovery-availability-complexity.html", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "02661582-b3d1-48d1-9d7b-c6a918a0ca33", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", + "service": "APIM", "severity": "보통", - "text": "깊고 얕은 클론으로 데이터 백업", - "waf": "신뢰도" + "text": "서브넷에 NSG(네트워크 보안 그룹)를 배포하여 APIM에서 들어오고 나가는 트래픽을 제한하거나 모니터링합니다.", + "waf": "안전" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "description": "RAGRS 스토리지 계정의 보조 엔드포인트를 사용하여 Blob 다운로드Download the blob using the secondary endpoint in RAGRS storage account", - "guid": "7abae48a-bd54-4cd7-ae2e-86768357c559", - "link": "https://techcommunity.microsoft.com/t5/azure-paas-blog/download-the-blob-using-secondary-endpoint-in-ragrs-storage/ba-p/2403750", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "67437a28-2721-4a2c-becd-caa54c8237a5", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", + "service": "APIM", "severity": "보통", - "text": "Azure Storage RA-GRS에 데이터 백업", - "waf": "신뢰도" + "text": "프라이빗 엔드포인트를 배포하여 APIM이 VNet에 배포되지 않은 경우 들어오는 트래픽을 필터링합니다.", + "waf": "안전" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "675c5ee8-5b85-49c7-944c-e3b1a28b875a", - "link": "https://learn.microsoft.com/azure/databricks/dev-tools/index-ci-cd", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "d698adbd-3288-44cb-b10a-9b572da395ae", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#disable-public-network-access", + "service": "APIM", "severity": "높다", - "text": "DevOps를 사용하여 코드 백업", - "waf": "신뢰도" + "text": "공용 네트워크 액세스 사용 안 함", + "waf": "안전" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "guid": "a1bf1038-9f03-4a4d-8ce4-63dbbbc8682a", - "link": "https://learn.microsoft.com/azure/databricks/administration-guide/disaster-recovery", - "service": "Azure Data Factory", - "severity": "높다", - "text": "액티브/액티브 또는 액티브/패시브 구성을 사용한 재해 복구 계획Plan for Disaster recovery using Active/Active or Active/Passive Configuration", - "waf": "신뢰도" + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "0674d750-0c6f-4ac0-8717-ceec04d0bdbd", + "link": "https://learn.microsoft.com/azure/api-management/automation-manage-api-management", + "service": "APIM", + "severity": "보통", + "text": "PowerShell 자동화 스크립트로 관리 간소화", + "waf": "작업" }, { - "arm-service": "Microsoft.DataFactory/datafactories", - "checklist": "DataBricks Review Checklist", - "description": "백업 및/또는 다른 Databricks 작업 영역으로 마이그레이션하기 위해 모든 Databricks 리소스를 기록하는 마이그레이션 패키지", - "guid": "5abc92a4-eda1-4dae-8cc8-5c47c6b781cc", - "link": "https://github.com/databrickslabs/migrate", - "service": "Azure Data Factory", + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "c385bfcd-49fd-4786-81ba-cedbb4c57345", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/app-platform/api-management/platform-automation-and-devops#design-recommendations", + "service": "APIM", "severity": "보통", - "text": "Databricks 마이그레이션 도구 사용", - "waf": "신뢰도" + "text": "Infrastructure-as-code를 통해 APIM을 구성합니다. Cloud Adaption Framework APIM 랜딩 존 가속기에서 DevOps 모범 사례 검토", + "waf": "작업" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "d7941d4a-7b6f-458f-8714-2f8f8c059ad4", - "link": "https://learn.microsoft.com/azure/api-management/api-management-error-handling-policies", + "guid": "6c3a27c0-197f-426c-9ffa-86fed51d9ab6", + "link": "https://learn.microsoft.com/azure/api-management/visual-studio-code-tutorial", "service": "APIM", "severity": "보통", - "text": "전역 수준에서 오류 처리 정책 구현", + "text": "더 빠른 API 개발을 위해 Visual Studio Code APIM 확장 사용 촉진", "waf": "작업" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "0b0c0765-ff37-4369-90bd-3eb23ce71b08", - "link": "https://learn.microsoft.com/azure/api-management/set-edit-policies?tabs=form#use-base-element-to-set-policy-evaluation-order", + "guid": "354f1c03-8112-4965-85ad-c0074bddf231", + "link": "https://learn.microsoft.com/azure/api-management/devops-api-development-templates", "service": "APIM", "severity": "보통", - "text": "모든 API 정책에 요소가 포함되어 있는지 확인합니다.", + "text": "워크플로에서 DevOps 및 CI/CD 구현", "waf": "작업" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "a5c45b03-93b6-42fe-b16b-8fccb6a79902", - "link": "https://learn.microsoft.com/azure/api-management/policy-fragments", + "guid": "b6439493-426a-45f3-9697-cf65baee208d", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates-for-clients", "service": "APIM", "severity": "보통", - "text": "정책 조각을 사용하여 여러 API에서 동일한 정책 정의를 반복하지 않도록 합니다.", - "waf": "작업" + "text": "클라이언트 인증서 인증을 사용하여 API 보안", + "waf": "안전" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "c3818a95-6ff3-4474-88dc-e809b46dad6a", - "link": "https://learn.microsoft.com/azure/api-management/monetization-support", + "guid": "2a67d143-1033-4c0a-8732-680896478f08", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates", "service": "APIM", "severity": "보통", - "text": "API로 수익을 창출할 계획이라면 '수익 창출 지원' 도움말에서 권장사항을 확인하세요", - "waf": "작업" + "text": "클라이언트 인증서 인증을 사용한 보안 백엔드 서비스", + "waf": "안전" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "a7d0840a-c8c4-4e83-adec-5ca578eb4049", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor#resource-logs", + "guid": "074435f5-4a46-41ac-b521-d6114cb5d845", + "link": "https://learn.microsoft.com/azure/api-management/mitigate-owasp-api-threats", "service": "APIM", - "severity": "높다", - "text": "진단 설정을 사용하도록 설정하여 로그를 Azure Monitor로 내보내기", - "waf": "작업" + "severity": "보통", + "text": "'OWASP API 보안 상위 10개 위협을 완화하기 위한 권장 사항' 문서를 검토하고 API에 적용할 수 있는 항목을 확인합니다.", + "waf": "안전" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "8691fa38-45ed-4299-a247-fecd98d35deb", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-app-insights", + "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", + "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", "service": "APIM", "severity": "보통", - "text": "더 자세한 원격 분석을 위해 Application Insights 사용", - "waf": "작업" + "text": "권한 부여 기능을 사용하여 백엔드 API에 대한 OAuth 2.0 토큰 관리 간소화", + "waf": "안전" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "55fd27bb-76ac-4a91-bc37-049e885be6b7", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-use-azure-monitor", + "guid": "2deee033-b906-4bc2-9f26-c8d3699fe091", + "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-manage-protocols-ciphers", "service": "APIM", "severity": "높다", - "text": "가장 중요한 메트릭에 대한 경고 구성", - "waf": "작업" + "text": "전송 중인 정보를 암호화할 때 최신 TLS 버전을 사용합니다. 가능한 경우 오래되고 불필요한 프로토콜과 암호를 사용하지 않도록 설정합니다.", + "waf": "안전" }, { "arm-service": "Microsoft.ApiManagement/service", "checklist": "Azure API Management Review", - "guid": "39460bdb-156f-4dc2-a87f-1e8c11ab0998", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#certificate-management-in-azure-key-vault", + "guid": "f8af3d94-1d2b-4070-846f-849197524258", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#im-8-restrict-the-exposure-of-credential-and-secrets", + "service": "APIM", + "severity": "높다", + "text": "비밀(명명된 값)이 안전하게 액세스하고 업데이트할 수 있도록 Azure Key Vault에 저장되었는지 확인합니다.", + "waf": "안전" + }, + { + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "791abd8b-7706-4e31-9569-afefde724be3", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#managed-identities", + "service": "APIM", + "severity": "보통", + "text": "가능할 때마다 관리 ID를 사용하여 다른 Azure 리소스에 인증", + "waf": "안전" + }, + { + "arm-service": "Microsoft.ApiManagement/service", + "checklist": "Azure API Management Review", + "guid": "220c4ca6-6688-476b-b2b5-425a78e6fb87", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", "service": "APIM", "severity": "높다", - "text": "사용자 지정 SSL 인증서가 안전하게 액세스하고 업데이트할 수 있도록 Azure Key Vault에 저장되어 있는지 확인합니다", + "text": "APIM 앞에 Application Gateway를 배포하여 WAF(웹 애플리케이션 방화벽) 사용Use Web Application Firewall (WAF) by deploying Application Gateway in of APIM", + "waf": "안전" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "3b7a56de-5020-4642-b3cb-c976e80b6d6d", + "link": "https://learn.microsoft.com/azure/logic-apps/single-tenant-overview-compare", + "service": "Logic Apps", + "severity": "높다", + "text": "비즈니스 및 SLO 요구 사항에 따라 올바른 Logic App 호스팅 계획 선택Select the right Logic App hosting plan based on your business & SLO requirements", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "3d7008bd-6bc1-4b03-8aa8-ec2a3b55786a", + "link": "https://learn.microsoft.com/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", + "service": "Logic Apps", + "severity": "높다", + "text": "영역 중복 및 가용성 영역을 사용하여 지역 오류로부터 논리 앱 보호Protect logic apps from region failures with zone redundancy and availability zones", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "1cda768f-a206-445d-8234-56f6a6e7286e", + "link": "https://learn.microsoft.com/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", + "service": "Logic Apps", + "severity": "높다", + "text": "중요한 워크로드에 대한 지역 간 DR 전략 고려", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "82118ec5-ed6f-4c68-9471-eb0da98a1b34", + "link": "https://learn.microsoft.com/azure/app-service/environment/intro", + "service": "Logic Apps", + "severity": "높다", + "text": "격리된 환경에 배포하는 경우 ASE(App Service Environment) v3을 사용하거나 마이그레이션합니다", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Web/sites", + "checklist": "Logic Apps checklist", + "guid": "74275fa5-9e08-4c7e-b096-13b538fe1501", + "link": "https://learn.microsoft.com/training/modules/deploy-azure-functions/", + "service": "Logic Apps", + "severity": "보통", + "text": "Azure DevOps 또는 GitHub를 활용하여 CI/CD를 간소화하고 논리 앱 코드를 보호합니다.", + "waf": "작업" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "스토리지와 관련된 Microsoft 클라우드 보안 벤치마크의 지침 적용", + "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", + "service": "Azure Storage", + "severity": "보통", + "text": "'스토리지에 대한 Azure 보안 기준'을 고려합니다.", + "waf": "안전" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "Azure Storage는 기본적으로 공용 IP 주소를 가지며 인터넷에 연결할 수 있습니다. 프라이빗 엔드포인트를 사용하면 액세스가 필요한 Azure Compute 리소스에만 Azure Storage를 안전하게 노출할 수 있으므로 공용 인터넷에 노출되지 않습니다", + "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", + "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", + "service": "Azure Storage", + "severity": "높다", + "text": "Azure Storage에 프라이빗 엔드포인트를 사용하는 것이 좋습니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "e9217997-5f6c-479d-8576-8f2adf706ec8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-ad-authentication-required-for-data-plane-access", - "service": "APIM", - "severity": "높다", - "text": "Azure AD를 사용하여 API(데이터 평면)에 들어오는 요청 보호", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "새로 만든 스토리지 계정은 ARM 배포 모델을 사용하여 생성되므로 RBAC, 감사 등이 모두 활성화됩니다. 구독에 클래식 배포 모델을 사용하는 이전 저장소 계정이 없는지 확인합니다.", + "guid": "30e37c3e-2971-41b2-963c-eee079b598de", + "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", + "service": "Azure Storage", + "severity": "보통", + "text": "이전 스토리지 계정이 '클래식 배포 모델'을 사용하지 않는지 확인", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "5e5f64ba-c90e-480e-8888-398d96cf0bfb", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-aad", - "service": "APIM", - "severity": "보통", - "text": "Microsoft Entra ID를 사용하여 개발자 포털에서 사용자 인증", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "Microsoft Defender를 활용하여 의심스러운 활동 및 잘못된 구성에 대해 알아보세요.", + "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", + "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", + "service": "Azure Storage", + "severity": "높다", + "text": "모든 스토리지 계정에 대해 Microsoft Defender 사용", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "f8e574ce-280f-49c8-b2ef-68279b081cf3", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-create-groups", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "일시 삭제 메커니즘을 사용하면 실수로 삭제된 Blob을 복구할 수 있습니다.", + "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", + "service": "Azure Storage", "severity": "보통", - "text": "제품의 가시성을 제어하기 위해 적절한 그룹을 만듭니다", + "text": "Blob에 대해 '일시 삭제' 사용Enable 'soft delete' for blobs", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "06862505-2d9a-4874-9491-2837b00a3475", - "link": "https://learn.microsoft.com/azure/api-management/backends", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "예를 들어 애플리케이션이 기밀성, 개인 정보 보호 또는 규정 준수를 위해 삭제된 정보가 즉시 삭제되도록 해야 하는 경우와 같이 특정 Blob 컨테이너에 대해 '일시 삭제'를 선택적으로 사용하지 않도록 설정하는 것이 좋습니다. ", + "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "service": "Azure Storage", "severity": "보통", - "text": "백엔드 기능을 사용하여 중복 API 백엔드 구성 제거", - "waf": "작업" + "text": "Blob에 대해 '일시 삭제' 사용 안 함", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "03b125d5-b69b-4739-b7fd-84b86da4933e", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-properties?tabs=azure-portal", - "service": "APIM", - "severity": "보통", - "text": "명명된 값을 사용하여 정책에서 사용할 수 있는 공통 값 저장", - "waf": "작업" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "컨테이너에 대한 일시 삭제를 사용하면 컨테이너가 삭제된 후 복구할 수 있습니다(예: 실수로 삭제한 작업에서 복구).", + "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", + "service": "Azure Storage", + "severity": "높다", + "text": "컨테이너에 대해 '일시 삭제' 사용Enable 'soft delete' for containers", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "beae759e-4ddb-4326-bf26-47f87d3454b6", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "예를 들어 애플리케이션이 기밀성, 개인 정보 보호 또는 규정 준수를 위해 삭제된 정보가 즉시 삭제되도록 해야 하는 경우와 같이 특정 Blob 컨테이너에 대해 '일시 삭제'를 선택적으로 사용하지 않도록 설정하는 것이 좋습니다. ", + "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "service": "Azure Storage", "severity": "보통", - "text": "DR의 경우 99.99% SLA를 위해 둘 이상의 지역에 걸쳐 확장된 배포와 함께 프리미엄 계층을 활용합니다", - "waf": "신뢰도" + "text": "컨테이너에 대해 '일시 삭제' 사용 안 함", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "9c8d1664-dd9a-49d4-bd83-950af0af4044", - "link": "https://learn.microsoft.com/azure/api-management/high-availability", - "service": "APIM", - "severity": "보통", - "text": "99.99%의 SLA 증가를 위해 둘 이상의 가용성 영역에 하나 이상의 단위를 배포합니다.", - "waf": "신뢰도" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "사용자가 삭제하기 전에 먼저 삭제 잠금을 제거하도록 강제하여 스토리지 계정의 우발적인 삭제를 방지합니다.", + "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "service": "Azure Storage", + "severity": "높다", + "text": "스토리지 계정에 대한 리소스 잠금 사용Enable resource locks on storage accounts", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "8d2db6e8-85c6-4118-a52c-ae76a4f27934", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#service-native-backup-capability", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "Blob에 대한 '법적 보존' 또는 '시간 기반 보존' 정책을 고려하면 Blob, 컨테이너 또는 스토리지 계정을 삭제할 수 없습니다. '불가능한'은 실제로 '불가능한'을 의미합니다. 스토리지 계정에 변경할 수 없는 Blob이 포함되면 해당 스토리지 계정을 '제거'하는 유일한 방법은 Azure 구독을 취소하는 것입니다.", + "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", + "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", + "service": "Azure Storage", "severity": "높다", - "text": "자동화된 백업 루틴이 있는지 확인", - "waf": "신뢰도" + "text": "변경할 수 없는 Blob 고려", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "43e60b94-7bca-43a2-aadf-efb04d63a485", - "link": "https://learn.microsoft.com/azure/api-management/retry-policy", - "service": "APIM", - "severity": "보통", - "text": "정책을 사용하여 장애 조치 백엔드 URL 및 캐싱을 추가하여 실패한 호출을 줄입니다.", - "waf": "신뢰도" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "스토리지 계정에 대한 보호되지 않는 HTTP/80 액세스를 사용하지 않도록 설정하여 모든 데이터 전송이 암호화되고 무결성이 보호되며 서버가 인증되도록 하는 것이 좋습니다. ", + "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Azure Storage", + "severity": "높다", + "text": "HTTPS 필요, 즉 스토리지 계정에서 포트 80 사용 안 함Require HTTPS, i.e. disable port 80 on the storage account", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "8210699f-8d43-45c2-8f19-57e54134bd8f", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-log-event-hubs", - "service": "APIM", - "severity": "낮다", - "text": "고성능 수준에서 기록해야 하는 경우 Event Hubs 정책을 고려합니다", - "waf": "작업" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "스토리지 계정에서 사용자 지정 도메인(호스트 이름)을 구성할 때 TLS/HTTPS가 필요한지 확인합니다. 이 경우 스토리지 계정 앞에 Azure CDN을 배치해야 할 수 있습니다.", + "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", + "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", + "service": "Azure Storage", + "severity": "높다", + "text": "HTTPS를 적용(HTTP 사용 안 함)할 때 스토리지 계정에 사용자 지정 도메인(CNAME)을 사용하지 않는지 확인합니다.", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "121bfc39-fa7b-4096-b93b-ab56c1bc0bed", - "link": "https://learn.microsoft.com/azure/api-management/api-management-sample-flexible-throttling", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "클라이언트가 SAS 토큰을 사용하여 Blob 데이터에 액세스할 때 HTTPS를 요구하면 자격 증명 손실 위험을 최소화하는 데 도움이 됩니다.", + "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", + "service": "Azure Storage", "severity": "보통", - "text": "제한 정책을 적용하여 초당 요청 수 제어Apply throttling policies to control the number of requests per second", - "training": "https://learn.microsoft.com/training/modules/protect-apis-on-api-management/", - "waf": "공연" + "text": "SAS(공유 액세스 서명) 토큰을 HTTPS 연결로만 제한", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "bb5f356b-3daf-47a2-a9ee-867a8100bbd5", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-autoscale", - "service": "APIM", - "severity": "보통", - "text": "부하가 증가할 때 인스턴스 수를 확장하도록 자동 크기 조정 구성Configure autoscaling to scale out the number of instances when the load increases", - "waf": "공연" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": ". 최신 TLS 버전을 적용하면 이전 버전을 사용하는 클라이언트의 요청이 거부됩니다. ", + "graph": "resources | where type == 'microsoft.storage/storageaccounts' | extend compliant = (isnull(properties.minimumTlsVersion) == false and properties.minimumTlsVersion in ('TLS1_2', 'TLS1_3')) | distinct id, compliant", + "guid": "e12be569-a18f-4562-8d5d-ce151b9e7d55", + "link": "https://learn.microsoft.com/azure/storage/common/transport-layer-security-configure-minimum-version", + "service": "Azure Storage", + "severity": "높다", + "text": "스토리지 계정에 대한 최신 TLS 버전 적용Enforce the latest TLS version for a storage account", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "84b94abb-59b6-4b9d-8587-3413669468e8", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-provision-self-hosted-gateway", - "service": "APIM", - "severity": "보통", - "text": "Azure에 백 엔드 API에 가까운 지역이 없는 자체 호스팅 게이트웨이를 배포합니다.", - "waf": "공연" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "가능한 경우 Microsoft Entra ID 토큰을 공유 액세스 서명보다 선호해야 합니다", + "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", + "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", + "service": "Azure Storage", + "severity": "높다", + "text": "Blob 액세스에 Microsoft Entra ID 토큰 사용Use Microsoft Entra ID tokens for blob access", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "1fe8db45-a017-4888-8c4d-4422583cfae0", - "link": "https://learn.microsoft.com/azure/api-management/upgrade-and-scale#upgrade-and-scale", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "사용자, 그룹 또는 응용 프로그램에 역할을 할당할 때 해당 보안 주체가 작업을 수행하는 데 필요한 권한만 부여합니다. 리소스에 대한 액세스를 제한하면 의도하지 않은 데이터 오용과 악의적인 데이터 오용을 모두 방지할 수 있습니다.", + "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", + "service": "Azure Storage", "severity": "보통", - "text": "프로덕션 워크로드에 프리미엄 계층을 사용합니다.", - "waf": "신뢰도" + "text": "IaM 권한의 최소 권한", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "1b8d68a4-66cd-44d5-ba94-3ee94440e8d6", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-deploy-multi-region#-route-api-calls-to-regional-backend-services", - "service": "APIM", - "severity": "보통", - "text": "다중 리전 모델에서는 Policies를 사용하여 가용성 또는 지연 시간에 따라 리전 백엔드로 요청을 라우팅합니다.", - "waf": "신뢰도" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "사용자 위임 SAS는 Azure AD(Azure Active Directory) 자격 증명과 SAS에 대해 지정된 권한으로 보호됩니다. 사용자 위임 SAS는 범위와 기능 측면에서 서비스 SAS와 유사하지만 서비스 SAS에 비해 보안상의 이점을 제공합니다. ", + "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", + "service": "Azure Storage", + "severity": "높다", + "text": "SAS를 사용하는 경우 스토리지 계정 키 기반 SAS보다 '사용자 위임 SAS'를 선호합니다.", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "46f07d33-ef9a-44e8-8f98-67c097c5d8cd", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits#api-management-limits", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "스토리지 계정 키('공유 키')에는 감사 기능이 거의 없습니다. 누가/언제 키 복사본을 가져왔는지 모니터링할 수 있지만 키가 여러 사람의 손에 들어가면 특정 사용자의 사용을 귀속시킬 수 없습니다. Entra ID 인증에만 의존하면 스토리지 액세스를 사용자에게 더 쉽게 연결할 수 있습니다. ", + "graph": "resources | where type == 'microsoft.storage/storageaccounts' | extend allowSharedKeyAccess = tostring(properties.allowSharedKeyAccess) | extend compliant = (isnotempty(allowSharedKeyAccess) and allowSharedKeyAccess == 'false') | distinct id, compliant", + "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", + "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", + "service": "Azure Storage", "severity": "높다", - "text": "APIM의 제한에 유의해야 합니다.", - "waf": "신뢰도" + "text": "Microsoft Entra ID 액세스(및 사용자 위임 SAS)만 지원되도록 스토리지 계정 키를 사용하지 않도록 설정하는 것이 좋습니다.", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "10f58602-f0f9-4d77-972a-956f6e0f2600", - "link": "https://learn.microsoft.com/en-us/azure/api-management/self-hosted-gateway-overview", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "활동 로그 데이터를 사용하여 스토리지 계정의 보안을 '언제', '누가', '무엇을' 및 '어떻게' 확인하거나 변경합니다(예: 스토리지 계정 키, 액세스 정책 등).", + "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", + "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", + "service": "Azure Storage", "severity": "높다", - "text": "자체 호스팅 게이트웨이 배포가 복원력이 있는지 확인합니다.", - "waf": "신뢰도" + "text": "Azure Monitor를 사용하여 스토리지 계정에 대한 컨트롤 플레인 작업을 감사하는 것이 좋습니다", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "7519e385-a88b-4d34-966b-6269d686e890", - "link": "https://learn.microsoft.com/azure/api-management/front-door-api-management", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "키 만료 정책을 사용하면 계정 액세스 키의 교체에 대한 미리 알림을 설정할 수 있습니다. 지정된 간격이 경과하고 키가 아직 회전되지 않은 경우 알림이 표시됩니다.", + "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", + "service": "Azure Storage", "severity": "보통", - "text": "다중 지역 배포를 위해 APIM 앞에서 Azure Front Door 사용Use Azure Front Door in front of APIM for multi-region deployment", - "waf": "공연" + "text": "스토리지 계정 키를 사용하는 경우 '키 만료 정책'을 사용하도록 설정하는 것이 좋습니다.", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "cd45c90e-7690-4753-930b-bf290c69c074", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#virtual-network-integration", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "SAS 만료 정책은 SAS가 유효한 권장 간격을 지정합니다. SAS 만료 정책은 서비스 SAS 또는 계정 SAS에 적용됩니다. 사용자가 권장 간격보다 큰 유효성 간격으로 서비스 SAS 또는 계정 SAS를 생성하면 경고가 표시됩니다.", + "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", + "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", + "service": "Azure Storage", "severity": "보통", - "text": "VNet(Virtual Network) 내에 서비스 배포Deploy the service within a Virtual Network (VNet)", + "text": "SAS 만료 정책을 구성하는 것이 좋습니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "02661582-b3d1-48d1-9d7b-c6a918a0ca33", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#network-security-group-support", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "저장된 액세스 정책은 스토리지 계정 키를 다시 생성할 필요 없이 서비스 SAS에 대한 사용 권한을 취소할 수 있는 옵션을 제공합니다. ", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", + "service": "Azure Storage", "severity": "보통", - "text": "서브넷에 NSG(네트워크 보안 그룹)를 배포하여 APIM에서 들어오고 나가는 트래픽을 제한하거나 모니터링합니다.", + "text": "SAS를 저장된 액세스 정책에 연결하는 것이 좋습니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "67437a28-2721-4a2c-becd-caa54c8237a5", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#azure-private-link", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", + "service": "Azure Storage", "severity": "보통", - "text": "프라이빗 엔드포인트를 배포하여 APIM이 VNet에 배포되지 않은 경우 들어오는 트래픽을 필터링합니다.", + "text": "체크 인된 연결 문자열 및 저장소 계정 키를 검색하도록 응용 프로그램의 소스 코드 리포지토리를 구성하는 것이 좋습니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "d698adbd-3288-44cb-b10a-9b572da395ae", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#disable-public-network-access", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "이상적으로 애플리케이션은 관리 ID를 사용하여 Azure Storage에 인증해야 합니다. 가능하지 않은 경우 Azure KeyVault 또는 동등한 서비스에 스토리지 자격 증명(연결 문자열, 스토리지 계정 키, SAS, 서비스 주체 자격 증명)을 사용하는 것이 좋습니다.", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", + "service": "Azure Storage", "severity": "높다", - "text": "공용 네트워크 액세스 사용 안 함", + "text": "Azure KeyVault에 연결 문자열을 저장하는 것이 좋습니다(관리 ID를 사용할 수 없는 시나리오에서).", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "0674d750-0c6f-4ac0-8717-ceec04d0bdbd", - "link": "https://learn.microsoft.com/azure/api-management/automation-manage-api-management", - "service": "APIM", - "severity": "보통", - "text": "PowerShell 자동화 스크립트로 관리 간소화", - "waf": "작업" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "c385bfcd-49fd-4786-81ba-cedbb4c57345", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/scenarios/app-platform/api-management/platform-automation-and-devops#design-recommendations", - "service": "APIM", - "severity": "보통", - "text": "Infrastructure-as-code를 통해 APIM을 구성합니다. Cloud Adaption Framework APIM 랜딩 존 가속기에서 DevOps 모범 사례 검토", - "waf": "작업" - }, - { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "6c3a27c0-197f-426c-9ffa-86fed51d9ab6", - "link": "https://learn.microsoft.com/azure/api-management/visual-studio-code-tutorial", - "service": "APIM", - "severity": "보통", - "text": "더 빠른 API 개발을 위해 Visual Studio Code APIM 확장 사용 촉진", - "waf": "작업" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "임시 SAS 서비스 SAS 또는 계정 SAS에서 가까운 만료 시간을 사용합니다. 이러한 방식으로 SAS가 손상되더라도 짧은 시간 동안만 유효합니다. 이 방법은 저장된 액세스 정책을 참조할 수 없는 경우에 특히 중요합니다. 또한 단기 만료 시간은 Blob에 업로드할 수 있는 시간을 제한하여 Blob에 쓸 수 있는 데이터의 양을 제한합니다.", + "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", + "severity": "높다", + "text": "임시 SAS의 유효 기간을 단축하기 위해 노력", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "354f1c03-8112-4965-85ad-c0074bddf231", - "link": "https://learn.microsoft.com/azure/api-management/devops-api-development-templates", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "SAS를 만들 때는 가능한 한 구체적이고 제한적이어야 합니다. 훨씬 더 광범위한 액세스를 제공하는 SAS보다 단일 리소스 및 작업에 대해 SAS를 선호합니다.", + "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", "severity": "보통", - "text": "워크플로에서 DevOps 및 CI/CD 구현", - "waf": "작업" + "text": "SAS에 좁은 범위 적용", + "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "b6439493-426a-45f3-9697-cf65baee208d", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates-for-clients", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "SAS에는 SAS를 사용하여 리소스를 요청할 수 있는 권한이 있는 클라이언트 IP 주소 또는 주소 범위에 대한 매개 변수가 포함될 수 있습니다. ", + "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", + "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", + "service": "Azure Storage", "severity": "보통", - "text": "클라이언트 인증서 인증을 사용하여 API 보안", + "text": "가능한 경우 SAS 범위를 특정 클라이언트 IP 주소로 지정하는 것이 좋습니다", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "2a67d143-1033-4c0a-8732-680896478f08", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-mutual-certificates", - "service": "APIM", - "severity": "보통", - "text": "클라이언트 인증서 인증을 사용한 보안 백엔드 서비스", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "SAS는 클라이언트가 업로드하는 데이터의 양을 제한할 수 없습니다. 시간 경과에 따른 스토리지 양의 가격 책정 모델을 감안할 때 클라이언트가 악의적으로 큰 콘텐츠를 업로드했는지 여부를 확인하는 것이 합리적일 수 있습니다.", + "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", + "service": "Azure Storage", + "severity": "낮다", + "text": "클라이언트가 SAS를 사용하여 파일을 업로드한 후 업로드된 데이터를 확인하는 것이 좋습니다. ", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "074435f5-4a46-41ac-b521-d6114cb5d845", - "link": "https://learn.microsoft.com/azure/api-management/mitigate-owasp-api-threats", - "service": "APIM", - "severity": "보통", - "text": "'OWASP API 보안 상위 10개 위협을 완화하기 위한 권장 사항' 문서를 검토하고 API에 적용할 수 있는 항목을 확인합니다.", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "'로컬 사용자 계정'을 사용하여 SFTP를 통해 Blob Storage에 액세스하는 경우 '일반적인' RBAC 컨트롤이 적용되지 않습니다. NFS 또는 REST를 통한 Blob 액세스는 SFTP 액세스보다 더 제한적일 수 있습니다. 안타깝게도 2023년 초부터 로컬 사용자는 현재 SFTP 엔드포인트에 대해 지원되는 유일한 ID 관리 형태입니다", + "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", + "service": "Azure Storage", + "severity": "높다", + "text": "SFTP: SFTP 액세스를 위한 '로컬 사용자'의 수를 제한하고 시간이 지남에 따라 액세스가 필요한지 여부를 감사합니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "5507c4b8-a7f8-41d6-9661-418c987100c9", - "link": "https://learn.microsoft.com/azure/api-management/authorizations-overview", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", + "service": "Azure Storage", "severity": "보통", - "text": "권한 부여 기능을 사용하여 백엔드 API에 대한 OAuth 2.0 토큰 관리 간소화", + "text": "SFTP: SFTP 엔드포인트는 POSIX와 유사한 ACL을 지원하지 않습니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "2deee033-b906-4bc2-9f26-c8d3699fe091", - "link": "https://learn.microsoft.com/azure/api-management/api-management-howto-manage-protocols-ciphers", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "스토리지는 CORS(Cross-Origin Resource Sharing), 즉 다른 도메인의 웹 앱이 동일 출처 정책을 완화할 수 있도록 하는 HTTP 기능을 지원합니다. CORS를 사용하도록 설정하는 경우 CorsRules를 최소 권한으로 유지합니다.", + "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", + "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", + "service": "Azure Storage", "severity": "높다", - "text": "전송 중인 정보를 암호화할 때 최신 TLS 버전을 사용합니다. 가능한 경우 오래되고 불필요한 프로토콜과 암호를 사용하지 않도록 설정합니다.", + "text": "지나치게 광범위한 CORS 정책 방지", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "f8af3d94-1d2b-4070-846f-849197524258", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#im-8-restrict-the-exposure-of-credential-and-secrets", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "미사용 데이터는 항상 서버 쪽에서 암호화되며 클라이언트 쪽에서도 암호화될 수 있습니다. 서버 쪽 암호화는 플랫폼 관리형 키(기본값) 또는 고객 관리형 키를 사용하여 발생할 수 있습니다. 클라이언트 쪽 암호화는 클라이언트가 Azure Storage에 Blob별로 암호화/암호 해독 키를 제공하도록 하거나 클라이언트 쪽에서 암호화를 완전히 처리하여 발생할 수 있습니다. 따라서 기밀 보장을 위해 Azure Storage에 전혀 의존하지 않습니다.", + "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", + "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", + "service": "Azure Storage", "severity": "높다", - "text": "비밀(명명된 값)이 안전하게 액세스하고 업데이트할 수 있도록 Azure Key Vault에 저장되었는지 확인합니다.", + "text": "미사용 데이터를 암호화하는 방법을 결정합니다. 데이터에 대한 스레드 모델을 이해합니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "791abd8b-7706-4e31-9569-afefde724be3", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#managed-identities", - "service": "APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", + "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", + "service": "Azure Storage", "severity": "보통", - "text": "가능할 때마다 관리 ID를 사용하여 다른 Azure 리소스에 인증", + "text": "어떤 플랫폼 암호화를 사용해야 하는지 확인합니다.", "waf": "안전" }, { - "arm-service": "Microsoft.ApiManagement/service", - "checklist": "Azure API Management Review", - "guid": "220c4ca6-6688-476b-b2b5-425a78e6fb87", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/api-management-security-baseline?toc=%2Fazure%2Fapi-management%2F&bc=%2Fazure%2Fapi-management%2Fbreadcrumb%2Ftoc.json#ns-6-deploy-web-application-firewall", - "service": "APIM", - "severity": "높다", - "text": "APIM 앞에 Application Gateway를 배포하여 WAF(웹 애플리케이션 방화벽) 사용Use Web Application Firewall (WAF) by deploying Application Gateway in of APIM", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", + "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "service": "Azure Storage", + "severity": "보통", + "text": "클라이언트 쪽 암호화를 사용해야 하는지 여부를 결정합니다.", "waf": "안전" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "3b7a56de-5020-4642-b3cb-c976e80b6d6d", - "link": "https://learn.microsoft.com/azure/logic-apps/single-tenant-overview-compare", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "description": "리소스 그래프 탐색기(리소스 | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true)를 활용하여 익명 Blob 액세스를 허용하는 스토리지 계정을 찾습니다.", + "graph": "resources | where type == 'microsoft.storage/storageaccounts' | extend compliant = (properties.allowBlobPublicAccess == 'false') | distinct id, compliant", + "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", + "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", + "service": "Azure Storage", "severity": "높다", - "text": "비즈니스 및 SLO 요구 사항에 따라 올바른 Logic App 호스팅 계획 선택Select the right Logic App hosting plan based on your business & SLO requirements", - "waf": "신뢰도" + "text": "공용 Blob 익명 액세스가 필요한지 또는 특정 스토리지 계정에 대해 사용하지 않도록 설정할 수 있는지 여부를 고려합니다. ", + "waf": "안전" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "3d7008bd-6bc1-4b03-8aa8-ec2a3b55786a", - "link": "https://learn.microsoft.com/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "cb8eb8c0-aa62-4a25-a495-6eaa8dc4a243", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-upgrade?tabs=azure-portal", + "service": "Azure Storage", "severity": "높다", - "text": "영역 중복 및 가용성 영역을 사용하여 지역 오류로부터 논리 앱 보호Protect logic apps from region failures with zone redundancy and availability zones", + "text": "성능 및 안정성 향상을 위해 storagev2 계정 유형 활용", "waf": "신뢰도" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "1cda768f-a206-445d-8234-56f6a6e7286e", - "link": "https://learn.microsoft.com/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "e05bbe20-9d49-4fda-9777-8424d116785c", + "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", + "service": "Azure Storage", "severity": "높다", - "text": "중요한 워크로드에 대한 지역 간 DR 전략 고려", + "text": "최고의 가용성을 위해 GRS, ZRS 또는 GZRS 스토리지 활용", "waf": "신뢰도" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "82118ec5-ed6f-4c68-9471-eb0da98a1b34", - "link": "https://learn.microsoft.com/azure/app-service/environment/intro", - "service": "Logic Apps", - "severity": "높다", - "text": "격리된 환경에 배포하는 경우 ASE(App Service Environment) v3을 사용하거나 마이그레이션합니다", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "2fa56c56-ad48-4408-be72-734c486ba280", + "link": "https://learn.microsoft.com/azure/storage/common/storage-disaster-recovery-guidance", + "service": "Azure Storage", + "severity": "보통", + "text": "장애 조치(failover) 후 쓰기 작업의 경우 고객 관리 장애 조치(failover)를 사용합니다. ", "waf": "신뢰도" }, { - "arm-service": "Microsoft.Web/sites", - "checklist": "Logic Apps checklist", - "guid": "74275fa5-9e08-4c7e-b096-13b538fe1501", - "link": "https://learn.microsoft.com/training/modules/deploy-azure-functions/", - "service": "Logic Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Storage Review Checklist", + "guid": "dc0590cf-65de-48e1-909c-cbd579266bcc", + "link": "https://learn.microsoft.com/azure/storage/common/storage-disaster-recovery-guidance#microsoft-managed-failover", + "service": "Azure Storage", "severity": "보통", - "text": "Azure DevOps 또는 GitHub를 활용하여 CI/CD를 간소화하고 논리 앱 코드를 보호합니다.", - "waf": "작업" + "text": "Microsoft 관리 장애 조치(failover) 세부 정보 이해", + "waf": "신뢰도" }, { "arm-service": "Microsoft.Storage/storageAccounts", "checklist": "Azure Storage Review Checklist", + "guid": "a274faa1-abfe-49d5-9d04-c3c4919cb1b3", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable?tabs=azure-portal", + "service": "Azure Storage", + "severity": "보통", + "text": "일시 삭제 사용", + "waf": "신뢰도" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", "description": "스토리지와 관련된 Microsoft 클라우드 보안 벤치마크의 지침 적용", "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", "service": "Azure Storage", "severity": "보통", - "text": "'스토리지에 대한 Azure 보안 기준'을 고려합니다.", + "text": "'스토리지에 대한 Azure 보안 기준' 고려", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "Azure Storage는 기본적으로 공용 IP 주소를 가지며 인터넷에 연결할 수 있습니다. 프라이빗 엔드포인트를 사용하면 액세스가 필요한 Azure Compute 리소스에만 Azure Storage를 안전하게 노출할 수 있으므로 공용 인터넷에 노출되지 않습니다", "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", @@ -9398,8 +10069,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "새로 만든 스토리지 계정은 ARM 배포 모델을 사용하여 생성되므로 RBAC, 감사 등이 모두 활성화됩니다. 구독에 클래식 배포 모델을 사용하는 이전 저장소 계정이 없는지 확인합니다.", + "checklist": "Azure Blob Storage Review", + "description": "새로 만든 저장소 계정은 ARM 배포 모델을 사용하여 만들어지므로 RBAC, 감사 등을 모두 사용할 수 있습니다. 구독에 클래식 배포 모델이 있는 이전 저장소 계정이 없는지 확인합니다.", "guid": "30e37c3e-2971-41b2-963c-eee079b598de", "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", "service": "Azure Storage", @@ -9409,8 +10080,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "Microsoft Defender를 활용하여 의심스러운 활동 및 잘못된 구성에 대해 알아보세요.", + "checklist": "Azure Blob Storage Review", + "description": "Microsoft Defender를 활용하여 의심스러운 활동 및 잘못된 구성에 대해 알아봅니다.", "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", "service": "Azure Storage", @@ -9420,7 +10091,7 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "일시 삭제 메커니즘을 사용하면 실수로 삭제된 Blob을 복구할 수 있습니다.", "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", @@ -9431,7 +10102,7 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "예를 들어 애플리케이션이 기밀성, 개인 정보 보호 또는 규정 준수를 위해 삭제된 정보가 즉시 삭제되도록 해야 하는 경우와 같이 특정 Blob 컨테이너에 대해 '일시 삭제'를 선택적으로 사용하지 않도록 설정하는 것이 좋습니다. ", "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", @@ -9442,8 +10113,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "컨테이너에 대한 일시 삭제를 사용하면 컨테이너가 삭제된 후 복구할 수 있습니다(예: 실수로 삭제한 작업에서 복구).", + "checklist": "Azure Blob Storage Review", + "description": "컨테이너에 대한 일시 삭제를 사용하면 컨테이너가 삭제된 후 컨테이너를 복구할 수 있습니다(예: 실수로 인한 삭제 작업에서 복구).", "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", "service": "Azure Storage", @@ -9453,7 +10124,7 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "예를 들어 애플리케이션이 기밀성, 개인 정보 보호 또는 규정 준수를 위해 삭제된 정보가 즉시 삭제되도록 해야 하는 경우와 같이 특정 Blob 컨테이너에 대해 '일시 삭제'를 선택적으로 사용하지 않도록 설정하는 것이 좋습니다. ", "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", @@ -9464,8 +10135,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "사용자가 삭제하기 전에 먼저 삭제 잠금을 제거하도록 강제하여 스토리지 계정의 우발적인 삭제를 방지합니다.", + "checklist": "Azure Blob Storage Review", + "description": "사용자가 삭제하기 전에 먼저 삭제 잠금을 제거하도록 강제하여 저장소 계정이 실수로 삭제되는 것을 방지합니다.", "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", "service": "Azure Storage", @@ -9475,8 +10146,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "Blob에 대한 '법적 보존' 또는 '시간 기반 보존' 정책을 고려하면 Blob, 컨테이너 또는 스토리지 계정을 삭제할 수 없습니다. '불가능한'은 실제로 '불가능한'을 의미합니다. 스토리지 계정에 변경할 수 없는 Blob이 포함되면 해당 스토리지 계정을 '제거'하는 유일한 방법은 Azure 구독을 취소하는 것입니다.", + "checklist": "Azure Blob Storage Review", + "description": "Blob에 대한 '법적 보존' 또는 '시간 기반 보존' 정책을 고려하면 Blob, 컨테이너 또는 스토리지 계정을 삭제할 수 없습니다. '불가능'은 실제로 '불가능'을 의미합니다. 스토리지 계정에 변경할 수 없는 Blob이 포함된 경우 해당 스토리지 계정을 '제거'하는 유일한 방법은 Azure 구독을 취소하는 것입니다.", "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", "service": "Azure Storage", @@ -9486,8 +10157,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "스토리지 계정에 대한 보호되지 않는 HTTP/80 액세스를 사용하지 않도록 설정하여 모든 데이터 전송이 암호화되고 무결성이 보호되며 서버가 인증되도록 하는 것이 좋습니다. ", + "checklist": "Azure Blob Storage Review", + "description": "모든 데이터 전송이 암호화되고, 무결성이 보호되고, 서버가 인증되도록 스토리지 계정에 대한 보호되지 않는 HTTP/80 액세스를 사용하지 않도록 설정하는 것이 좋습니다. ", "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", "service": "Azure Storage", @@ -9497,18 +10168,18 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "스토리지 계정에서 사용자 지정 도메인(호스트 이름)을 구성할 때 TLS/HTTPS가 필요한지 확인합니다. 이 경우 스토리지 계정 앞에 Azure CDN을 배치해야 할 수 있습니다.", + "checklist": "Azure Blob Storage Review", + "description": "스토리지 계정에서 사용자 지정 도메인(호스트 이름)을 구성할 때 TLS/HTTPS가 필요한지 여부를 확인합니다. 이 경우 저장소 계정 앞에 Azure CDN을 배치해야 할 수 있습니다.", "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", "service": "Azure Storage", "severity": "높다", - "text": "HTTPS를 적용(HTTP 사용 안 함)할 때 스토리지 계정에 사용자 지정 도메인(CNAME)을 사용하지 않는지 확인합니다.", + "text": "HTTPS를 적용할 때(HTTP 사용 안 함) 스토리지 계정에 사용자 지정 도메인(CNAME)을 사용하지 않는지 확인합니다.", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "클라이언트가 SAS 토큰을 사용하여 Blob 데이터에 액세스할 때 HTTPS를 요구하면 자격 증명 손실 위험을 최소화하는 데 도움이 됩니다.", "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", @@ -9519,30 +10190,18 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": ". 최신 TLS 버전을 적용하면 이전 버전을 사용하는 클라이언트의 요청이 거부됩니다. ", - "graph": "resources | where type == 'microsoft.storage/storageaccounts' | extend compliant = (isnull(properties.minimumTlsVersion) == false and properties.minimumTlsVersion in ('TLS1_2', 'TLS1_3')) | distinct id, compliant", - "guid": "e12be569-a18f-4562-8d5d-ce151b9e7d55", - "link": "https://learn.microsoft.com/azure/storage/common/transport-layer-security-configure-minimum-version", - "service": "Azure Storage", - "severity": "높다", - "text": "스토리지 계정에 대한 최신 TLS 버전 적용Enforce the latest TLS version for a storage account", - "waf": "안전" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "가능한 경우 Microsoft Entra ID 토큰을 공유 액세스 서명보다 선호해야 합니다", + "checklist": "Azure Blob Storage Review", + "description": "AAD 토큰은 가능한 경우 공유 액세스 서명보다 우선해야 합니다", "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", "service": "Azure Storage", "severity": "높다", - "text": "Blob 액세스에 Microsoft Entra ID 토큰 사용Use Microsoft Entra ID tokens for blob access", + "text": "Blob 액세스에 Azure AD(Azure Active Directory) 토큰 사용Use Azure Active Directory (Azure AD) tokens for blob access", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "사용자, 그룹 또는 응용 프로그램에 역할을 할당할 때 해당 보안 주체가 작업을 수행하는 데 필요한 권한만 부여합니다. 리소스에 대한 액세스를 제한하면 의도하지 않은 데이터 오용과 악의적인 데이터 오용을 모두 방지할 수 있습니다.", "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", "service": "Azure Storage", @@ -9552,8 +10211,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "사용자 위임 SAS는 Azure AD(Azure Active Directory) 자격 증명과 SAS에 대해 지정된 권한으로 보호됩니다. 사용자 위임 SAS는 범위와 기능 측면에서 서비스 SAS와 유사하지만 서비스 SAS에 비해 보안상의 이점을 제공합니다. ", + "checklist": "Azure Blob Storage Review", + "description": "사용자 위임 SAS는 Azure AD(Azure Active Directory) 자격 증명과 SAS에 지정된 권한으로 보호됩니다. 사용자 위임 SAS는 범위와 기능 측면에서 서비스 SAS와 유사하지만 서비스 SAS에 비해 보안상의 이점을 제공합니다. ", "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", "service": "Azure Storage", @@ -9563,53 +10222,52 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "스토리지 계정 키('공유 키')에는 감사 기능이 거의 없습니다. 누가/언제 키 복사본을 가져왔는지 모니터링할 수 있지만 키가 여러 사람의 손에 들어가면 특정 사용자의 사용을 귀속시킬 수 없습니다. Entra ID 인증에만 의존하면 스토리지 액세스를 사용자에게 더 쉽게 연결할 수 있습니다. ", - "graph": "resources | where type == 'microsoft.storage/storageaccounts' | extend allowSharedKeyAccess = tostring(properties.allowSharedKeyAccess) | extend compliant = (isnotempty(allowSharedKeyAccess) and allowSharedKeyAccess == 'false') | distinct id, compliant", + "checklist": "Azure Blob Storage Review", + "description": "스토리지 계정 키('공유 키')에는 감사 기능이 거의 없습니다. 누가/언제 키 사본을 가져왔는지 모니터링할 수 있지만, 키가 여러 사람의 손에 들어가면 특정 사용자의 사용을 귀속시키는 것은 불가능합니다. AAD 인증에만 의존하면 스토리지 액세스를 사용자에게 더 쉽게 연결할 수 있습니다. ", "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", "service": "Azure Storage", "severity": "높다", - "text": "Microsoft Entra ID 액세스(및 사용자 위임 SAS)만 지원되도록 스토리지 계정 키를 사용하지 않도록 설정하는 것이 좋습니다.", + "text": "AAD 액세스(및 사용자 위임 SAS)만 지원되도록 스토리지 계정 키를 사용하지 않도록 설정하는 것이 좋습니다.", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "활동 로그 데이터를 사용하여 스토리지 계정의 보안을 '언제', '누가', '무엇을' 및 '어떻게' 확인하거나 변경합니다(예: 스토리지 계정 키, 액세스 정책 등).", + "checklist": "Azure Blob Storage Review", + "description": "활동 로그 데이터를 사용하여 스토리지 계정의 보안을 보거나 변경하는 '시기', '누가', '무엇을' 및 '방법'(예: 스토리지 계정 키, 액세스 정책 등)을 식별합니다.", "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", "service": "Azure Storage", "severity": "높다", - "text": "Azure Monitor를 사용하여 스토리지 계정에 대한 컨트롤 플레인 작업을 감사하는 것이 좋습니다", + "text": "Azure Monitor를 사용하여 스토리지 계정에 대한 컨트롤 플레인 작업을 감사하는 것이 좋습니다.", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "키 만료 정책을 사용하면 계정 액세스 키의 교체에 대한 미리 알림을 설정할 수 있습니다. 지정된 간격이 경과하고 키가 아직 회전되지 않은 경우 알림이 표시됩니다.", + "checklist": "Azure Blob Storage Review", + "description": "키 만료 정책을 사용하면 계정 액세스 키 교체에 대한 미리 알림을 설정할 수 있습니다. 지정된 간격이 경과하고 키가 아직 회전되지 않은 경우 알림이 표시됩니다.", "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", "service": "Azure Storage", "severity": "보통", - "text": "스토리지 계정 키를 사용하는 경우 '키 만료 정책'을 사용하도록 설정하는 것이 좋습니다.", + "text": "스토리지 계정 키를 사용하는 경우 '키 만료 정책'을 사용하도록 설정하는 것이 좋습니다", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "SAS 만료 정책은 SAS가 유효한 권장 간격을 지정합니다. SAS 만료 정책은 서비스 SAS 또는 계정 SAS에 적용됩니다. 사용자가 권장 간격보다 큰 유효성 간격으로 서비스 SAS 또는 계정 SAS를 생성하면 경고가 표시됩니다.", + "checklist": "Azure Blob Storage Review", + "description": "SAS 만료 정책은 SAS가 유효한 권장 간격을 지정합니다. SAS 만료 정책은 서비스 SAS 또는 계정 SAS에 적용됩니다. 사용자가 권장 간격보다 큰 유효 간격을 사용하여 서비스 SAS 또는 계정 SAS를 생성하면 경고가 표시됩니다.", "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", "service": "Azure Storage", "severity": "보통", - "text": "SAS 만료 정책을 구성하는 것이 좋습니다.", + "text": "SAS 만료 정책 구성 고려", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "저장된 액세스 정책은 스토리지 계정 키를 다시 생성할 필요 없이 서비스 SAS에 대한 사용 권한을 취소할 수 있는 옵션을 제공합니다. ", + "checklist": "Azure Blob Storage Review", + "description": "저장된 액세스 정책은 스토리지 계정 키를 다시 생성할 필요 없이 서비스 SAS에 대한 권한을 취소하는 옵션을 제공합니다. ", "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", "service": "Azure Storage", @@ -9619,7 +10277,7 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", "service": "Azure Storage", @@ -9629,8 +10287,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "이상적으로 애플리케이션은 관리 ID를 사용하여 Azure Storage에 인증해야 합니다. 가능하지 않은 경우 Azure KeyVault 또는 동등한 서비스에 스토리지 자격 증명(연결 문자열, 스토리지 계정 키, SAS, 서비스 주체 자격 증명)을 사용하는 것이 좋습니다.", + "checklist": "Azure Blob Storage Review", + "description": "이상적으로 애플리케이션은 관리 ID를 사용하여 Azure Storage에 인증해야 합니다. 이렇게 할 수 없는 경우 Azure KeyVault 또는 동등한 서비스에 스토리지 자격 증명(연결 문자열, 스토리지 계정 키, SAS, 서비스 주체 자격 증명)을 사용하는 것이 좋습니다.", "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", "service": "Azure Storage", @@ -9640,8 +10298,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "임시 SAS 서비스 SAS 또는 계정 SAS에서 가까운 만료 시간을 사용합니다. 이러한 방식으로 SAS가 손상되더라도 짧은 시간 동안만 유효합니다. 이 방법은 저장된 액세스 정책을 참조할 수 없는 경우에 특히 중요합니다. 또한 단기 만료 시간은 Blob에 업로드할 수 있는 시간을 제한하여 Blob에 쓸 수 있는 데이터의 양을 제한합니다.", + "checklist": "Azure Blob Storage Review", + "description": "임시 SAS 서비스 SAS 또는 계정 SAS에서 단기 만료 시간을 사용합니다. 이러한 방식으로 SAS가 손상되더라도 짧은 시간 동안만 유효합니다. 이 방법은 저장된 액세스 정책을 참조할 수 없는 경우에 특히 중요합니다. 또한 단기 만료 시간은 업로드에 사용할 수 있는 시간을 제한하여 Blob에 쓸 수 있는 데이터의 양을 제한합니다.", "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", "service": "Azure Storage", @@ -9651,7 +10309,7 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "SAS를 만들 때는 가능한 한 구체적이고 제한적이어야 합니다. 훨씬 더 광범위한 액세스를 제공하는 SAS보다 단일 리소스 및 작업에 대해 SAS를 선호합니다.", "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", @@ -9662,19 +10320,19 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "SAS에는 SAS를 사용하여 리소스를 요청할 수 있는 권한이 있는 클라이언트 IP 주소 또는 주소 범위에 대한 매개 변수가 포함될 수 있습니다. ", "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", "service": "Azure Storage", "severity": "보통", - "text": "가능한 경우 SAS 범위를 특정 클라이언트 IP 주소로 지정하는 것이 좋습니다", + "text": "가능한 경우 SAS의 범위를 특정 클라이언트 IP 주소로 지정하는 것이 좋습니다", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "SAS는 클라이언트가 업로드하는 데이터의 양을 제한할 수 없습니다. 시간 경과에 따른 스토리지 양의 가격 책정 모델을 감안할 때 클라이언트가 악의적으로 큰 콘텐츠를 업로드했는지 여부를 확인하는 것이 합리적일 수 있습니다.", + "checklist": "Azure Blob Storage Review", + "description": "SAS는 클라이언트가 업로드하는 데이터의 양을 제한할 수 없습니다. 시간 경과에 따른 스토리지 양의 가격 책정 모델을 고려할 때 클라이언트가 악의적으로 큰 콘텐츠를 업로드했는지 여부를 확인하는 것이 합리적일 수 있습니다.", "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", "service": "Azure Storage", "severity": "낮다", @@ -9683,18 +10341,18 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "description": "'로컬 사용자 계정'을 사용하여 SFTP를 통해 Blob Storage에 액세스하는 경우 '일반적인' RBAC 컨트롤이 적용되지 않습니다. NFS 또는 REST를 통한 Blob 액세스는 SFTP 액세스보다 더 제한적일 수 있습니다. 안타깝게도 2023년 초부터 로컬 사용자는 현재 SFTP 엔드포인트에 대해 지원되는 유일한 ID 관리 형태입니다", "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", "service": "Azure Storage", "severity": "높다", - "text": "SFTP: SFTP 액세스를 위한 '로컬 사용자'의 수를 제한하고 시간이 지남에 따라 액세스가 필요한지 여부를 감사합니다.", + "text": "SFTP: SFTP 액세스에 대한 '로컬 사용자'의 수를 제한하고 시간이 지남에 따라 액세스가 필요한지 여부를 감사합니다.", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", "service": "Azure Storage", @@ -9704,8 +10362,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "스토리지는 CORS(Cross-Origin Resource Sharing), 즉 다른 도메인의 웹 앱이 동일 출처 정책을 완화할 수 있도록 하는 HTTP 기능을 지원합니다. CORS를 사용하도록 설정하는 경우 CorsRules를 최소 권한으로 유지합니다.", + "checklist": "Azure Blob Storage Review", + "description": "스토리지는 CORS(Cross-Origin Resource Sharing), 즉 다른 도메인의 웹앱이 동일 출처 정책을 완화할 수 있도록 하는 HTTP 기능을 지원합니다. CORS를 사용하도록 설정할 때 CorsRules를 최소 권한으로 유지합니다.", "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", "service": "Azure Storage", @@ -9715,8 +10373,8 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "미사용 데이터는 항상 서버 쪽에서 암호화되며 클라이언트 쪽에서도 암호화될 수 있습니다. 서버 쪽 암호화는 플랫폼 관리형 키(기본값) 또는 고객 관리형 키를 사용하여 발생할 수 있습니다. 클라이언트 쪽 암호화는 클라이언트가 Azure Storage에 Blob별로 암호화/암호 해독 키를 제공하도록 하거나 클라이언트 쪽에서 암호화를 완전히 처리하여 발생할 수 있습니다. 따라서 기밀 보장을 위해 Azure Storage에 전혀 의존하지 않습니다.", + "checklist": "Azure Blob Storage Review", + "description": "미사용 데이터는 항상 서버 쪽에서 암호화되며 클라이언트 쪽에서도 암호화될 수 있습니다. 서버 쪽 암호화는 플랫폼 관리형 키(기본값) 또는 고객 관리형 키를 사용하여 발생할 수 있습니다. 클라이언트 쪽 암호화는 클라이언트가 Azure Storage에 Blob별로 암호화/암호 해독 키를 제공하거나 클라이언트 쪽에서 암호화를 완전히 처리하여 발생할 수 있습니다. 따라서 기밀성 보장을 위해 Azure Storage에 전혀 의존하지 않습니다.", "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", "service": "Azure Storage", @@ -9726,86 +10384,35 @@ }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", "service": "Azure Storage", "severity": "보통", - "text": "어떤 플랫폼 암호화를 사용해야 하는지 확인합니다.", + "text": "사용해야 하는 플랫폼 암호화를 결정합니다.", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", + "checklist": "Azure Blob Storage Review", "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", "service": "Azure Storage", "severity": "보통", - "text": "클라이언트 쪽 암호화를 사용해야 하는지 여부를 결정합니다.", + "text": "사용해야 하는 클라이언트 쪽 암호화를 결정합니다.", "waf": "안전" }, { "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "description": "리소스 그래프 탐색기(리소스 | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true)를 활용하여 익명 Blob 액세스를 허용하는 스토리지 계정을 찾습니다.", - "graph": "resources | where type == 'microsoft.storage/storageaccounts' | extend compliant = (properties.allowBlobPublicAccess == 'false') | distinct id, compliant", + "checklist": "Azure Blob Storage Review", + "description": "Resource Graph Explorer(resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true)를 활용하여 익명 Blob 액세스를 허용하는 스토리지 계정을 찾습니다.", "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", "service": "Azure Storage", "severity": "높다", - "text": "공용 Blob 익명 액세스가 필요한지 또는 특정 스토리지 계정에 대해 사용하지 않도록 설정할 수 있는지 여부를 고려합니다. ", + "text": "공용 Blob 액세스가 필요한지 또는 특정 스토리지 계정에 대해 사용하지 않도록 설정할 수 있는지 여부를 고려합니다. ", "waf": "안전" }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "guid": "cb8eb8c0-aa62-4a25-a495-6eaa8dc4a243", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-upgrade?tabs=azure-portal", - "service": "Azure Storage", - "severity": "높다", - "text": "성능 및 안정성 향상을 위해 storagev2 계정 유형 활용", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "guid": "e05bbe20-9d49-4fda-9777-8424d116785c", - "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", - "service": "Azure Storage", - "severity": "높다", - "text": "최고의 가용성을 위해 GRS, ZRS 또는 GZRS 스토리지 활용", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "guid": "2fa56c56-ad48-4408-be72-734c486ba280", - "link": "https://learn.microsoft.com/azure/storage/common/storage-disaster-recovery-guidance", - "service": "Azure Storage", - "severity": "보통", - "text": "장애 조치(failover) 후 쓰기 작업의 경우 고객 관리 장애 조치(failover)를 사용합니다. ", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "guid": "dc0590cf-65de-48e1-909c-cbd579266bcc", - "link": "https://learn.microsoft.com/azure/storage/common/storage-disaster-recovery-guidance#microsoft-managed-failover", - "service": "Azure Storage", - "severity": "보통", - "text": "Microsoft 관리 장애 조치(failover) 세부 정보 이해", - "waf": "신뢰도" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Storage Review Checklist", - "guid": "a274faa1-abfe-49d5-9d04-c3c4919cb1b3", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable?tabs=azure-portal", - "service": "Azure Storage", - "severity": "보통", - "text": "일시 삭제 사용", - "waf": "신뢰도" - }, { "arm-service": "Microsoft.DBforMySQL/servers", "checklist": "MySQL Review Checklist", @@ -10670,7 +11277,7 @@ ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/waf_checklist.pt.json b/checklists/waf_checklist.pt.json index 777ed2fc..64c7095b 100644 --- a/checklists/waf_checklist.pt.json +++ b/checklists/waf_checklist.pt.json @@ -1372,6 +1372,208 @@ "text": "Aproveite o Azure DevOps ou o GitHub para simplificar o CI/CD e proteger seu código do Aplicativo de Função", "waf": "Operações" }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Desative a exportação de imagens para evitar a exfiltração de dados. Observe que isso impedirá a importação de imagens para outra instância do ACR.", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "Alto", + "text": "Desabilitar a exportação de imagem do Registro de Contêiner do Azure", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Habilite a visibilidade de conformidade de auditoria habilitando o Azure Policy para o Registro de Contêiner do Azure", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "Alto", + "text": "Habilitar Políticas do Azure para o Registro de Contêiner do Azure", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "O Azure Key Vault (AKV) é usado para armazenar uma chave de assinatura que pode ser utilizada por?notação?com o plug-in AKV de notação (azure-kv) para assinar e verificar imagens de contêiner e outros artefatos. O ACR (Registro de Contêiner do Azure) permite que você anexe essas assinaturas usando o?az?ou?oras? Comandos da CLI.", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "Alto", + "text": "Assinar e verificar contêineres com notação (Notary v2)", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "O Registro de Contêiner do Azure criptografa automaticamente imagens e outros artefatos que você armazena. Por padrão, o Azure criptografa automaticamente o conteúdo do Registro em repouso usando chaves gerenciadas pelo serviço. Usando uma chave gerenciada pelo cliente, você pode complementar a criptografia padrão com uma camada de criptografia adicional.", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "Média", + "text": "Criptografar o registro com uma chave gerenciada pelo cliente", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Usar identidades gerenciadas para proteger o acesso RBAC ACRPull/Push de aplicativos cliente", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "Alto", + "text": "Usar identidades gerenciadas para se conectar em vez de entidades de serviço", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "A conta de administrador local está desabilitada por padrão e não deve ser habilitada. Em vez disso, use métodos de acesso baseados em token ou RBAC", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "Alto", + "text": "Desabilitar a autenticação local para acesso ao plano de gerenciamento", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Desabilitar a conta de administrador e atribuir funções RBAC a entidades de segurança para operações de pull/push do ACR", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "Alto", + "text": "Atribuir funções RBAC AcrPull e AcrPush em vez de conceder acesso administrativo a entidades de identidade", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Desabilitar acesso anônimo de pull/push", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "Média", + "text": "Desabilitar o acesso pull anônimo", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "A autenticação de token não dá suporte à atribuição a uma entidade de segurança do AAD. Quaisquer tokens fornecidos podem ser usados por qualquer pessoa que possa acessar o token", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "Alto", + "text": "Desabilitar tokens de acesso no escopo do repositório", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Implantar imagens de contêiner em um ACR por trás de um ponto de extremidade privado em uma rede confiável", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "Alto", + "text": "Implantar imagens de um ambiente confiável", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Somente tokens com um público-alvo do ACR podem ser usados para autenticação. Usado ao habilitar políticas de acesso condicional para ACR", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "Média", + "text": "Desabilitar tokens de audiência do ARM do Azure para autenticação", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Configure uma configuração de diagnóstico para enviar 'repositoryEvents' e 'LoginEvents' para o Log Analytics como o destino central para registro em log e monitoramento. Isso permite que você monitore a atividade do plano de controle no próprio recurso do ACR.", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "Média", + "text": "Habilitar o log de diagnóstico", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "O serviço dá suporte à desabilitação do acesso à rede pública usando a regra de filtragem de ACL IP no nível do serviço (não NSG ou Firewall do Azure) ou usando uma opção de alternância 'Desabilitar Acesso à Rede Pública'", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "Média", + "text": "Controle o acesso à rede de entrada com Link Privado", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Desative o acesso à rede pública se o acesso à rede de entrada for protegido usando o Link Privado", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "Média", + "text": "Desabilitar o acesso à rede pública", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Somente o SKU do ACR Premium dá suporte ao acesso ao Link Privado", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "Média", + "text": "Usar um SKU do Registro de Contêiner do Azure que dá suporte ao Link Privado (SKU Premium)", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "O Azure Defender para contêineres ou serviço equivalente deve ser usado para verificar se há vulnerabilidades em imagens de contêiner", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "Baixo", + "text": "Habilitar o Defender para Contêineres para verificar se há vulnerabilidades no Registro de Contêiner do Azure", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Implante código confiável que foi validado e verificado em busca de vulnerabilidades de acordo com as práticas de DevSecOps.", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "severity": "Média", + "text": "Implantar imagens de contêiner validadas", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Use as versões mais recentes de plataformas, linguagens de programação, protocolos e estruturas com suporte.", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "Alto", + "text": "Use plataformas, linguagens, protocolos e frameworks atualizados", + "waf": "Segurança" + }, { "arm-service": "microsoft.eventhub/namespaces", "checklist": "Azure Event Hub Review", @@ -1962,6 +2164,17 @@ "text": "Restringir o uso de usuários locais em cargas de trabalho sql no Synapse", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Nenhuma configuração adicional é necessária, pois isso é habilitado em uma implantação padrão.", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Criptografar dados confidenciais em trânsito", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -1973,6 +2186,15 @@ "text": "Usar identidade gerenciada para autenticar nos serviços", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Habilitar a criptografia de dados em repouso por padrão", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -1983,6 +2205,17 @@ "text": "Separe e limite usuários altamente privilegiados/administrativos e habilite políticas condicionais e de MFA", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Usar o Keyvaults para armazenar sua CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Usar a opção de chave gerenciada pelo cliente na criptografia de dados em repouso quando necessário", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2015,6 +2248,16 @@ "text": "Usar o espaço de trabalho vnet gerenciado para restringir o acesso pela Internet pública", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use a ID do Microsoft Entra como o método de autenticação padrão.", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "severity": "Alto", + "text": "Use o Microsoft Entra ID como o método de autenticação padrão e desabilite o acesso local sempre que possível", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2026,6 +2269,16 @@ "text": "Configure pontos de extremidade privados para se conectar aos serviços externos e desabilitar o acesso público", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use a ID do Microsoft Entra como o método de autenticação padrão.", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Usar identidade gerenciada para autenticar nos serviços", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2036,6 +2289,15 @@ "text": "Se habilitar o acesso público, é altamente recomendável configurar regras de firewall IP", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Configurar políticas de acesso condicional para restringir o acesso no plano de dados", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2046,6 +2308,16 @@ "text": "Implante VMs SHIR em sua rede virtual se você estiver trabalhando com dados confidenciais que não devem sair da rede corporativa", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Restringir a exposição de chaves e secerts", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "severity": "Alto", + "text": "Use o Azure Key Vaults para armazenar segredos e créditos.", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2057,6 +2329,37 @@ "text": "Habilitar DEP (Proteção contra Exfiltração de Dados)", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "severity": "Alto", + "text": "Separar e limitar usuários altamente privilegiados/administrativos", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Quando você cria um namespace dos Hubs de Eventos, uma regra de política chamada RootManageSharedAccessKey é criada automaticamente para o namespace. Essa política tem permissões de gerenciamento para todo o namespace. É recomendável que você trate essa regra como uma conta raiz administrativa e não a use em seu aplicativo. Você pode criar regras de política adicionais na guia Configurar para o namespace no portal, por meio do PowerShell ou da CLI do Azure. Evite o uso de métodos ou contas de autenticação locais, eles devem ser desativados sempre que possível. Em vez disso, use o Azure AD para autenticar sempre que possível.", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Autenticar o acesso aos recursos dos Hubs de Eventos usando SAS (assinaturas de acesso compartilhado) e restringir usuários locais", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Use o RBAC (controle de acesso baseado em função) do Azure para gerenciar o acesso a recursos do Azure por meio de atribuições de função internas. As funções RBAC do Azure podem ser atribuídas a usuários, grupos, entidades de serviço e identidades gerenciadas.", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Usar RBACs do Azure para granular o acesso ", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2068,6 +2371,16 @@ "text": "Criptografia de dados em repouso usando chaves gerenciadas pelo cliente para workspace", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "O serviço dá suporte à desabilitação do acesso à rede pública usando a regra de filtragem de ACL IP no nível do serviço (não NSG ou Firewall do Azure) ou usando uma opção de alternância 'Desabilitar Acesso à Rede Pública'.", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Desativar acesso à rede pública", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2079,6 +2392,15 @@ "text": "Criptografia de dados em trânsito ", "waf": "Segurança" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Usar Vnets para isolar o tráfego na rede restrita ", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2090,111 +2412,385 @@ "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", + "arm-service": "microsoft.eventhub/namespaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Restrinja o uso de métodos de autenticação local para acesso ao plano de dados. Em vez disso, use a ID do Microsoft Entra como o método de autenticação padrão para controlar o acesso ao plano de dados.", - "guid": "0bdf4cc2-efc4-4d76-8c31-d25ffbb47a39", - "service": "Azure Data Factory", - "severity": "Alto", - "text": "Restrinja o uso de usuários locais sempre que necessário", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "Média", + "text": "Implante pontos de extremidade privados para todos os recursos do Azure que dão suporte ao recurso Link Privado para estabelecer um ponto de acesso privado para os recursos.", "waf": "Segurança" }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "As identidades gerenciadas eliminam a necessidade de gerenciar credenciais. As identidades gerenciadas fornecem uma identidade para a instância de serviço ao se conectar a recursos que dão suporte à autenticação do Microsoft Entra.", - "guid": "3a040ed3-2947-498b-8178-a2c5a46ceb54", - "link": "https://learn.microsoft.com/azure/data-factory/data-factory-service-identity", + "description": "Você pode armazenar credenciais ou valores secretos em um Azure Key Vault e usá-los durante a execução do pipeline para passar para suas atividades.", + "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", "service": "Azure Data Factory", "severity": "Média", - "text": "Usar identidade gerenciada para autenticar nos serviços", + "text": "Usar segredos do Azure Key Vault em atividades de pipeline", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Se não for necessário para operações administrativas de rotina, desabilite ou restrinja todas as contas de administrador local apenas para uso emergencial.", - "guid": "4350d092-d234-4292-a752-8537a551c5bf", - "service": "Azure Data Factory", - "severity": "Alto", - "text": "Separe e limite usuários altamente privilegiados/administrativos e habilite políticas condicionais e de MFA", + "description": "A malha controla o acesso a dados usando espaços de trabalho. Nos espaços de trabalho, os dados aparecem na forma de itens de malha e os usuários não podem visualizar ou usar itens (dados), a menos que você conceda a eles acesso ao espaço de trabalho. Você pode encontrar mais informações sobre permissões de espaço de trabalho e item em Modelo de permissão.", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Use funções de espaço de trabalho para fornecer acesso aos usuários nos dados", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "6898a535-e337-4897-b31b-67d67be5962a", - "service": "Azure Data Factory", + "description": "O OneLake RBAC usa atribuições de função para aplicar permissões a seus membros.", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", "severity": "Média", - "text": "Implante VMs SHIR em sua rede virtual se você estiver trabalhando com dados confidenciais que não devem sair da rede corporativa", + "text": "Use o RBAC no Onelake para fornecer acesso refinado aos dados em Tabelas/Arquivos Onelake ", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Quando você cria um runtime de integração do Azure em uma rede virtual gerenciada do Data Factory, o runtime de integração é provisionado com a rede virtual gerenciada. Ele usa pontos de extremidade privados para se conectar com segurança a armazenamentos de dados com suporte.", - "guid": "1193846d-697c-4c39-8ed1-6b2d186f0a12", - "service": "Azure Data Factory", + "description": "Leve em conta o acesso do usuário no local de destino e de origem do atalho", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", "severity": "Média", - "text": "Usar o IR de vnet gerenciado para restringir o acesso pela Internet pública para o Azure Integration Runtime", + "text": "Ao usar atalhos, a identidade do usuário também deve ter acesso ao local de destino do atalho", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Os pontos de extremidade privados gerenciados são pontos de extremidade privados criados na rede virtual gerenciada do Data Factory que estabelece um link privado para os recursos do Azure. O Data Factory gerencia esses pontos de extremidade privados em seu nome.", - "guid": "41bddde6-8a47-47cd-bb48-61bc3bc10ae6", - "link": "https://learn.microsoft.com/azure/data-factory/managed-virtual-network-private-endpoint#managed-private-endpoints", - "service": "Azure Data Factory", + "description": "Nem todos os usuários precisam ter acesso a todo o espaço de trabalho usando funções, portanto, restrinja a atribuição de funções em todo o espaço de trabalho e compartilhe o item apenas com o usuário usando o recurso de compartilhamento de item ou permissão de gerenciamento no Fabric", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", "severity": "Média", - "text": "Configurar pontos de extremidade privados gerenciados para se conectar a recursos usando o Azure IR gerenciado", + "text": "Restringir o fornecimento de função no nível do espaço de trabalho aos usuários, em vez de compartilhar um item apenas com os usuários", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Esta é uma configuração padrão", - "guid": "6ceb5443-5135-4922-9442-93bb628637a5", - "service": "Azure Data Factory", + "description": "Use recursos como RLS, CLS e mascaramento de dados dinâmicos para aprimorar seus requisitos de segurança de dados em cargas de trabalho SQL.", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", "severity": "Média", - "text": "Criptografia de dados em repouso por chaves gerenciadas da Microsoft", + "text": "Limite o acesso aos dados definindo RLS, CLS e mascaramento de dados dinâmicos em pontos de extremidade de análise de SQL e Warehouse", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Esta é uma configuração padrão", - "guid": "5119b08e-8f58-4543-a7e9-cec166cd072a", - "service": "Azure Data Factory", + "description": "Use recursos como RLS e OLS no Power BI para ter mais recursos de segurança em modelos semânticos", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", "severity": "Média", - "text": "Criptografia de dados em trânsito por chaves gerenciadas pela Microsoft", + "text": "Limitar o acesso aos dados definindo RLS e OLS em modelos semânticos no Power BI", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Segurança" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "Quando você especifica uma chave gerenciada pelo cliente, o Data Factory usa a chave do sistema de fábrica e a CMK para criptografar os dados do cliente. A falta de qualquer um resultaria em Negação de acesso aos dados e à fábrica.", - "guid": "f9b241a9-98a5-435e-9378-97e71ca7da8c", - "link": "https://learn.microsoft.com/azure/data-factory/enable-customer-managed-key", - "service": "Azure Data Factory", + "description": "No Fabric, todos os dados armazenados no OneLake são criptografados em repouso", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", "severity": "Média", - "text": "Criptografia de dados em trânsito por BYOK (chaves gerenciadas pelo cliente)", + "text": "Criptografar dados em repouso", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Os dados em trânsito pela Internet pública entre os serviços da Microsoft são sempre criptografados com pelo menos TLS 1.2. A malha negocia com o TLS 1.3 sempre que possível.", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Criptografar dados em trânsito", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", "waf": "Segurança" }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "faa62a15-9495-46da-a7dc-3a23267b2258", - "link": "https://learn.microsoft.com/azure/data-factory/store-credentials-in-key-vault, https:/learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "description": "Restrinja o uso de métodos de autenticação local para acesso ao plano de dados. Em vez disso, use a ID do Microsoft Entra como o método de autenticação padrão para controlar o acesso ao plano de dados.", + "guid": "0bdf4cc2-efc4-4d76-8c31-d25ffbb47a39", "service": "Azure Data Factory", "severity": "Alto", - "text": "Armazenar senhas e segredos no Azure Key Vault", + "text": "Restrinja o uso de usuários locais sempre que necessário", "waf": "Segurança" }, { "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "guid": "6db55f57-9603-4334-adf9-cc23418db612", - "service": "Microsoft Purview", + "description": "Não há necessidade de fazer nada. Cada solicitação para se conectar ao Fabric é autenticada com a ID do Microsoft Entra, permitindo que os usuários se conectem com segurança ao Fabric de seu escritório corporativo, ao trabalhar em casa ou de um local remoto.", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Usar o Microsoft Entra ID como método de autenticação padrão", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "As identidades gerenciadas eliminam a necessidade de gerenciar credenciais. As identidades gerenciadas fornecem uma identidade para a instância de serviço ao se conectar a recursos que dão suporte à autenticação do Microsoft Entra.", + "guid": "3a040ed3-2947-498b-8178-a2c5a46ceb54", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-service-identity", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Usar identidade gerenciada para autenticar nos serviços", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Uma identidade de workspace do Fabric é uma entidade de serviço gerenciada automaticamente que pode ser associada a um workspace do Fabric. As identidades do workspace podem ser criadas nas configurações do workspace de qualquer workspace, exceto Meus workspaces. Uma identidade de workspace recebe automaticamente a função de colaborador do workspace e tem acesso aos itens do workspace. Limitação: Falha na gravação no destino do atalho ao usar a identidade do workspace como método de autenticação. As conexões com workspace-identity-authentication só podem ser usadas em atalhos Onelake e pipelines de dados.", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Usar a identidade do workspace para autenticar nos serviços", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Se não for necessário para operações administrativas de rotina, desabilite ou restrinja todas as contas de administrador local apenas para uso emergencial.", + "guid": "4350d092-d234-4292-a752-8537a551c5bf", + "service": "Azure Data Factory", + "severity": "Alto", + "text": "Separe e limite usuários altamente privilegiados/administrativos e habilite políticas condicionais e de MFA", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Conceder as permissões de identidade na conta de armazenamento", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Fornecer funções RBAC na conta de armazenamento para a identidade gerenciada para fazer uma conexão bem-sucedida", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Desabilitar o acesso pela Internet pública e configurar regras de firewall ou regras de serviços confiáveis", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Os workspaces do Fabric com uma identidade de workspace podem ler ou gravar com segurança em contas do Azure Data Lake Storage Gen2 habilitadas para firewall por meio do acesso confiável ao workspace para atalhos do OneLake.", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Configurar o acesso ao workspace confiável para acessar a conta de armazenamento atrás do firewall ", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6898a535-e337-4897-b31b-67d67be5962a", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Implante VMs SHIR em sua rede virtual se você estiver trabalhando com dados confidenciais que não devem sair da rede corporativa", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "As redes virtuais gerenciadas são redes virtuais criadas e gerenciadas pelo Microsoft Fabric para cada workspace do Fabric. As redes virtuais gerenciadas fornecem isolamento de rede para cargas de trabalho do Fabric Spark, o que significa que os clusters de computação são implantados em uma rede dedicada e não fazem mais parte da rede virtual compartilhada. Ele só tem suporte para carga de trabalho do Spark no Fabric.", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Use a opção vnet gerenciada se você tiver necessidades de isolamento de rede", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Quando você cria um runtime de integração do Azure em uma rede virtual gerenciada do Data Factory, o runtime de integração é provisionado com a rede virtual gerenciada. Ele usa pontos de extremidade privados para se conectar com segurança a armazenamentos de dados com suporte.", + "guid": "1193846d-697c-4c39-8ed1-6b2d186f0a12", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Usar o IR de vnet gerenciado para restringir o acesso pela Internet pública para o Azure Integration Runtime", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Os pontos de extremidade privados gerenciados são recursos que permitem acesso seguro e privado a fontes de dados de cargas de trabalho do Fabric Spark. Você não pode usar o pool inicial com PE gerenciado", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Configurar pontos de extremidade privados gerenciados para acessar os serviços do Azure", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Os pontos de extremidade privados gerenciados são pontos de extremidade privados criados na rede virtual gerenciada do Data Factory que estabelece um link privado para os recursos do Azure. O Data Factory gerencia esses pontos de extremidade privados em seu nome.", + "guid": "41bddde6-8a47-47cd-bb48-61bc3bc10ae6", + "link": "https://learn.microsoft.com/azure/data-factory/managed-virtual-network-private-endpoint#managed-private-endpoints", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Configurar pontos de extremidade privados gerenciados para se conectar a recursos usando o Azure IR gerenciado", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "O Fabric usa um endereço IP privado da sua rede virtual. O endpoint permite que os usuários em sua rede se comuniquem com o Fabric pelo endereço IP privado usando links privados.", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Configure Links Privados para acessar recursos em sua própria rede virtual do Azure, ou seja, o tráfego que vem em seu ambiente do Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Quando um usuário autentica, o acesso é determinado com base em um conjunto de políticas que podem incluir endereço IP, localização e dispositivos gerenciados.", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Configurar o acesso condicional do Microsoft Entra ID se um usuário estiver tentando acessar seu ambiente do Fabric", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "No Azure, uma marca de serviço é um grupo definido de endereços IP que é gerenciado automaticamente, como um grupo, para minimizar a complexidade das atualizações ou alterações nas regras de segurança de rede.", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Você pode usar marcas de serviço do Azure para habilitar conexões de e para o Microsoft Fabric.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "opcional", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Você pode adicionar URLs de estrutura à sua lista de permissões", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "opcional", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Você pode adicionar URLs do Power BI à sua lista de permissões", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "O gateway de dados permite que você conecte seu Azure e outros serviços de dados ao Microsoft Fabric e ao Power Platform para se comunicar com segurança com a fonte de dados, executar consultas e transmitir resultados de volta ao serviço.", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "Média", + "text": "Configurar e usar o gateway de dados local ou o gateway de dados Vnet para se conectar a fontes locais ou atrás de uma rede virtual", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Usando o Link Privado do Azure, você pode se conectar a várias implantações de PaaS (plataforma como serviço) no Azure por meio de um ponto de extremidade privado. Um ponto de extremidade privado é um endereço IP privado em uma rede virtual e sub-rede específicas", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Configurar Links Privados para se conectar a fontes na Vnet do cliente e no data factory", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Esta é uma configuração padrão", + "guid": "6ceb5443-5135-4922-9442-93bb628637a5", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Criptografia de dados em repouso por chaves gerenciadas da Microsoft", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Esta é uma configuração padrão", + "guid": "5119b08e-8f58-4543-a7e9-cec166cd072a", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Criptografia de dados em trânsito por chaves gerenciadas pela Microsoft", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Quando você especifica uma chave gerenciada pelo cliente, o Data Factory usa a chave do sistema de fábrica e a CMK para criptografar os dados do cliente. A falta de qualquer um resultaria em Negação de acesso aos dados e à fábrica.", + "guid": "f9b241a9-98a5-435e-9378-97e71ca7da8c", + "link": "https://learn.microsoft.com/azure/data-factory/enable-customer-managed-key", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Criptografia de dados em trânsito por BYOK (chaves gerenciadas pelo cliente)", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "faa62a15-9495-46da-a7dc-3a23267b2258", + "link": "https://learn.microsoft.com/azure/data-factory/store-credentials-in-key-vault, https:/learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "Alto", + "text": "Armazenar senhas e segredos no Azure Key Vault", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Você pode armazenar credenciais ou valores secretos em um Azure Key Vault e usá-los durante a execução do pipeline para passar para suas atividades.", + "guid": "6f4a1652-bddd-4ea8-a487-cdec4861bc3b", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Usar segredos do Azure Key Vault em atividades de pipeline", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Você pode criptografar e armazenar credenciais para qualquer um dos seus armazenamentos de dados locais (serviços vinculados com informações confidenciais) em um computador com runtime de integração auto-hospedada.", + "guid": "c14aeb7e-66e8-4d9a-9bec-218e6436b173", + "link": "https://learn.microsoft.com/azure/data-factory/encrypt-credentials-self-hosted-integration-runtime", + "service": "Azure Data Factory", + "severity": "Média", + "text": "Criptografar credenciais para locais usando armazenamentos de dados SHIR no Azure Data Factory", + "waf": "Segurança" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6db55f57-9603-4334-adf9-cc23418db612", + "service": "Microsoft Purview", "severity": "Média", "text": "Definir funções e responsabilidades para gerenciar o Microsoft Purview no painel de controle e no plano de dados", "waf": "Segurança" @@ -2455,6 +3051,17 @@ "text": "Limite os direitos de criação de cluster.", "waf": "Segurança" }, + { + "arm-service": "Microsoft.Databricks/workspaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Os administradores de conta podem definir uma configuração de workspace chamada RestrictWorkspaceAdmins para restringir os administradores de workspace a alterar apenas um proprietário de trabalho para si mesmos e a configuração de execução de trabalho para uma entidade de serviço na qual eles têm a função de Usuário de Entidade de Serviço.", + "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", + "severity": "Alto", + "text": "Restringir administradores do workspace", + "waf": "Segurança" + }, { "arm-service": "Microsoft.Databricks/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -2621,46 +3228,6 @@ "text": "Usar conjuntos de réplicas para DR", "waf": "Fiabilidade" }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "Alto", - "text": "Habilite a redundância de zona para o Cache do Azure para Redis. O Cache do Azure para Redis dá suporte a configurações redundantes de zona nas camadas Premium e Enterprise. Um cache redundante de zona pode colocar seus nós em diferentes zonas de disponibilidade do Azure na mesma região. Ele elimina a interrupção do data center ou AZ como um único ponto de falha e aumenta a disponibilidade geral do cache.", - "waf": "Fiabilidade" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", - "severity": "Média", - "text": "Configure a persistência de dados para uma instância do Cache do Azure para Redis. Como os dados do cache são armazenados na memória, uma falha rara e não planejada de vários nós pode fazer com que todos os dados sejam descartados. Para evitar a perda completa de dados, a persistência do Redis permite que você tire instantâneos periódicos de dados na memória e os armazene em sua conta de armazenamento.", - "waf": "Fiabilidade" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", - "severity": "Média", - "text": "Use a conta de armazenamento com redundância geográfica para persistir o Cache do Azure para dados Redis ou zonalmente redundante onde a redundância geográfica não está disponível", - "waf": "Fiabilidade" - }, - { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", - "severity": "Média", - "text": "Configure a replicação geográfica passiva para instâncias do Cache Premium do Azure para Redis. A replicação geográfica é um mecanismo para vincular duas ou mais instâncias do Cache do Azure para Redis, normalmente abrangendo duas regiões do Azure. A replicação geográfica foi projetada principalmente para recuperação de desastres entre regiões. Duas instâncias de cache de camada Premium são conectadas por meio de replicação geográfica de uma forma que fornece leituras e gravações no cache primário e que os dados são replicados para o cache secundário.", - "waf": "Fiabilidade" - }, { "arm-service": "Microsoft.AppPlatform/Spring", "checklist": "Azure Spring Apps Review", @@ -5713,2297 +6280,1929 @@ "waf": "Operações" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Aplicar as orientações do benchmark de segurança na nuvem da Microsoft relacionadas ao armazenamento", - "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", - "service": "Azure Storage", - "severity": "Média", - "text": "Considere a 'linha de base de segurança do Azure para armazenamento'", - "waf": "Segurança" + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "ac1d6380-f866-4bbd-a9b4-b1ee5d7908b8", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#availability-zones", + "service": "IoT", + "severity": "Alto", + "text": "Aproveitar zonas de disponibilidade, se aplicável regionalmente (isso é habilitado automaticamente)", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "O Armazenamento do Azure, por padrão, tem um endereço IP público e pode ser acessado pela Internet. Os pontos de extremidade privados permitem expor com segurança o Armazenamento do Azure apenas aos recursos de Computação do Azure que precisam de acesso, eliminando assim a exposição à Internet pública", - "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", - "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", - "service": "Azure Storage", - "severity": "Alto", - "text": "Considere o uso de pontos de extremidade privados para o Armazenamento do Azure", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "As contas de armazenamento recém-criadas são criadas usando o modelo de implantação ARM, para que o RBAC, a auditoria, etc., estejam todos habilitados. Verifique se não há contas de armazenamento antigas com modelo de implantação clássico em uma assinatura", - "guid": "30e37c3e-2971-41b2-963c-eee079b598de", - "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "35f651e8-0124-4ef7-8c57-658e38609e6e", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", + "service": "IoT", "severity": "Média", - "text": "Verifique se as contas de armazenamento mais antigas não estão usando o 'modelo de implantação clássico'", - "waf": "Segurança" + "text": "Esteja ciente dos failovers iniciados pela Microsoft. Eles são exercidos pela Microsoft em raras situações para fazer failover de todos os hubs IoT de uma região afetada para a região geo-emparelhada correspondente.", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Aproveite o Microsoft Defender para saber mais sobre atividades suspeitas e configurações incorretas.", - "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", - "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", - "service": "Azure Storage", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "4ed3e490-dc06-4a1e-b467-5d0239d85540", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#cross-region-dr", + "service": "IoT", "severity": "Alto", - "text": "Habilitar o Microsoft Defender para todas as suas contas de armazenamento", - "waf": "Segurança" + "text": "Considere uma estratégia de DR entre regiões para cargas de trabalho críticas", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "O mecanismo soft-delete permite recuperar blobs excluídos acidentalmente.", - "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", - "service": "Azure Storage", - "severity": "Média", - "text": "Ativar 'exclusão suave' para blobs", - "waf": "Segurança" + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "a11ecab0-db47-46f7-9aa7-17764e7e45a1", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", + "service": "IoT", + "severity": "Alto", + "text": "Saiba como acionar um failover manual.", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere desativar seletivamente a \"exclusão suave\" para determinados contêineres de blob, por exemplo, se o aplicativo tiver que garantir que as informações excluídas sejam imediatamente excluídas, por exemplo, por motivos de confidencialidade, privacidade ou conformidade. ", - "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", - "service": "Azure Storage", - "severity": "Média", - "text": "Desativar 'exclusão suave' para blobs", - "waf": "Segurança" + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "f9db8dfb-1194-460b-aedd-34dd6a69db22", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#failback", + "service": "IoT", + "severity": "Alto", + "text": "Saiba como fazer failback após um failover.", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "A exclusão suave para contêineres permite que você recupere um contêiner depois que ele tenha sido excluído, por exemplo, recuperar de uma operação de exclusão acidental.", - "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", - "service": "Azure Storage", - "severity": "Alto", - "text": "Ativar 'exclusão suave' para contêineres", - "waf": "Segurança" + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "7bc1c396-2461-4698-b57f-30ca69525252", + "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/considerations/regions", + "service": "VNet", + "severity": "Média", + "text": "Implante seus recursos de conectividade de zona de destino do Azure em várias regiões, para que você possa dar suporte rapidamente a zonas de destino de aplicativos de várias regiões e cenários de recuperação de desastre.", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere desativar seletivamente a \"exclusão suave\" para determinados contêineres de blob, por exemplo, se o aplicativo tiver que garantir que as informações excluídas sejam imediatamente excluídas, por exemplo, por motivos de confidencialidade, privacidade ou conformidade. ", - "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "70c15989-c726-42c7-b0d3-24b7375b9201", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/considerations-recommendations", + "service": "Entra", "severity": "Média", - "text": "Desativar 'exclusão suave' para contêineres", - "waf": "Segurança" + "text": "Use um locatário do Entra para gerenciar seus recursos do Azure, a menos que você tenha um requisito regulatório ou comercial claro para multilocatários.", + "training": "https://learn.microsoft.com/training/modules/deploy-resources-scopes-bicep/2-understand-deployment-scopes", + "waf": "Operações" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Evita a exclusão acidental de uma conta de armazenamento, forçando o usuário a remover primeiro o bloqueio de exclusão, antes da exclusão", - "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", - "service": "Azure Storage", - "severity": "Alto", - "text": "Habilitar bloqueios de recursos em contas de armazenamento", - "waf": "Segurança" + "checklist": "Azure Landing Zone Review", + "guid": "6309957b-821a-43d1-b9d9-7fcf1802b747", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", + "service": "Entra", + "severity": "Baixo", + "text": "Use a abordagem de Automação Multilocatário para gerenciar seus locatários de ID do Microsoft Entra.", + "training": "https://learn.microsoft.com/entra/architecture/multi-tenant-user-management-introduction/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere políticas de \"retenção legal\" ou \"retenção baseada em tempo\" para blobs, de modo que seja impossível excluir o blob, o contêiner ou a conta de armazenamento. Por favor, note que \"impossível\" significa na verdade \"impossível\"; uma vez que uma conta de armazenamento contém um blob imutável, a única maneira de 'se livrar' dessa conta de armazenamento é cancelando a assinatura do Azure.", - "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", - "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "78e11934-499a-45ed-8ef7-aae5578f0ecf", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", + "service": "Entra", "severity": "Alto", - "text": "Considere blobs imutáveis", - "waf": "Segurança" + "text": "Use o Azure Lighthouse para gerenciamento de vários locatários com as mesmas IDs.", + "training": "https://learn.microsoft.com/azure/lighthouse/concepts/cross-tenant-management-experience", + "waf": "Operações" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Considere desabilitar o acesso HTTP/80 desprotegido à conta de armazenamento, para que todas as transferências de dados sejam criptografadas, protegidas por integridade e o servidor seja autenticado. ", - "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "5d82e6df-6f61-42f2-82e2-3132d293be3d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "service": "Entra", "severity": "Alto", - "text": "Exigir HTTPS, ou seja, desativar a porta 80 na conta de armazenamento", - "waf": "Segurança" + "text": "Se você conceder a um parceiro acesso para administrar seu locatário, use o Azure Lighthouse.", + "training": "https://learn.microsoft.com/azure/lighthouse/how-to/onboard-customer", + "waf": "Custar" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Ao configurar um domínio personalizado (nome do host) em uma conta de armazenamento, verifique se você precisa de TLS/HTTPS; em caso afirmativo, talvez seja necessário colocar a CDN do Azure na frente da sua conta de armazenamento.", - "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", - "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "348ef254-c27d-442e-abba-c7571559ab91", + "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", + "service": "Entra", "severity": "Alto", - "text": "Ao impor HTTPS (desabilitando HTTP), verifique se você não usa domínios personalizados (CNAME) para a conta de armazenamento.", + "text": "Aplique um modelo RBAC que se alinhe ao seu modelo operacional de nuvem. Escopo e Atribuição entre Grupos de Gerenciamento e Assinaturas.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Exigir HTTPS quando um cliente usa um token SAS para acessar dados de blob ajuda a minimizar o risco de perda de credenciais.", - "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "12e7f983-f630-4472-8dd6-9c5b5c2622f5", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", + "service": "Entra", "severity": "Média", - "text": "Limitar tokens de assinatura de acesso compartilhado (SAS) somente a conexões HTTPS", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Os tokens AAD devem ser favorecidos em relação às assinaturas de acesso compartilhado, sempre que possível", - "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", - "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", - "service": "Azure Storage", - "severity": "Alto", - "text": "Usar tokens do Azure Active Directory (Azure AD) para acesso de blob", + "text": "Use apenas o tipo de autenticação Conta corporativa ou de estudante para todos os tipos de conta. Evite usar a conta da Microsoft", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Ao atribuir uma função a um usuário, grupo ou aplicativo, conceda a essa entidade de segurança apenas as permissões necessárias para que eles executem suas tarefas. Limitar o acesso aos recursos ajuda a evitar o uso indevido não intencional e mal-intencionado de seus dados.", - "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", + "service": "Entra", "severity": "Média", - "text": "Privilégio mínimo nas permissões do IaM", + "text": "Use apenas grupos para atribuir permissões. Adicione grupos locais ao grupo Somente ID do Entra se um sistema de gerenciamento de grupo já estiver em vigor.", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Uma SAS de delegação de usuário é protegida com credenciais do Azure Active Directory (Azure AD) e também pelas permissões especificadas para a SAS. Uma SAS de delegação de usuário é análoga a uma SAS de serviço em termos de escopo e função, mas oferece benefícios de segurança em relação à SAS de serviço. ", - "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", + "service": "Entra", "severity": "Alto", - "text": "Ao usar o SAS, prefira o SAS de delegação de usuário ao SAS baseado em chave de conta de armazenamento.", + "text": "Imponha políticas de Acesso Condicional da ID do Microsoft Entra para qualquer usuário com direitos a ambientes do Azure.", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "As chaves de conta de armazenamento ('chaves compartilhadas') têm pouquíssimos recursos de auditoria. Embora possa ser monitorado em quem/quando foi obtida uma cópia das chaves, uma vez que as chaves estão nas mãos de várias pessoas, é impossível atribuir o uso a um usuário específico. Depender exclusivamente da autenticação do AAD facilita a vinculação do acesso ao armazenamento a um usuário. ", - "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", - "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", + "service": "Entra", "severity": "Alto", - "text": "Considere desabilitar as chaves de conta de armazenamento, para que somente o acesso ao AAD (e a delegação de usuários SAS) seja suportado.", + "text": "Imponha a autenticação multifator para qualquer usuário com direitos aos ambientes do Azure.", + "training": "https://learn.microsoft.com/entra/identity/authentication/concept-mandatory-multifactor-authentication", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Use os dados do Registro de atividades para identificar \"quando\", \"quem\", \"o que\" e \"como\" a segurança da sua conta de armazenamento está sendo visualizada ou alterada (ou seja, chaves de conta de armazenamento, políticas de acesso, etc.).", - "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", - "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", - "service": "Azure Storage", - "severity": "Alto", - "text": "Considere usar o Azure Monitor para auditar as operações do plano de controle na conta de armazenamento", + "checklist": "Azure Landing Zone Review", + "guid": "14658d35-58fd-4772-99b8-21112df27ee4", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "service": "Entra", + "severity": "Média", + "text": "Imponha o Microsoft Entra ID Privileged Identity Management (PIM) para estabelecer acesso permanente zero e privilégios mínimos.", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Uma política de expiração de chave permite que você defina um lembrete para a rotação das chaves de acesso da conta. O lembrete será exibido se o intervalo especificado tiver decorrido e as teclas ainda não tiverem sido giradas.", - "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", + "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", + "service": "Entra", "severity": "Média", - "text": "Ao usar chaves de conta de armazenamento, considere habilitar uma 'política de expiração de chave'", + "text": "Se estiver planejando alternar dos Serviços de Domínio Active Directory para os serviços de domínio Entra, avalie a compatibilidade de todas as cargas de trabalho.", + "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Uma diretiva de expiração SAS especifica um intervalo recomendado sobre o qual a SAS é válida. As políticas de expiração do SAS se aplicam a um SAS de serviço ou a um SAS de conta. Quando um usuário gera SAS de serviço ou SAS de conta com um intervalo de validade maior do que o intervalo recomendado, ele verá um aviso.", - "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", - "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", - "service": "Azure Storage", - "severity": "Média", - "text": "Considere configurar uma política de expiração SAS", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "As políticas de acesso armazenado oferecem a opção de revogar permissões para uma SAS de serviço sem precisar gerar novamente as chaves da conta de armazenamento. ", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.aad/domainservices' | extend replicaSets = properties.replicaSets | where array_length(replicaSets) < 2 | project name=name, id=id, tags=tags, param1=strcat('replicaSetLocation:', replicaSets[0].location)", + "guid": "0dd4e625-9c4b-4a56-b54a-4357bac12761", + "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", + "service": "Entra", "severity": "Média", - "text": "Considere vincular o SAS a uma política de acesso armazenado", - "waf": "Segurança" + "text": "Ao usar o Microsoft Entra Domain Services, use conjuntos de réplicas. Os conjuntos de réplicas melhorarão a resiliência do domínio gerenciado e permitirão que você implante em regiões adicionais. ", + "training": "https://learn.microsoft.com/training/modules/understand-azure-active-directory/6-examine-azure-domain-services", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", + "service": "Entra", "severity": "Média", - "text": "Considere configurar o repositório de código-fonte do aplicativo para detectar cadeias de conexão com check-in e chaves de conta de armazenamento.", + "text": "Integre os logs de ID do Microsoft Entra com o Azure Monitor central da plataforma. O Azure Monitor permite uma única fonte de verdade sobre dados de log e monitoramento no Azure, oferecendo às organizações opções nativas de nuvem para atender aos requisitos de coleta e retenção de logs.", + "training": "https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Idealmente, seu aplicativo deve estar usando uma identidade gerenciada para autenticar no Armazenamento do Azure. Se isso não for possível, considere ter a credencial de armazenamento (cadeia de conexão, chave de conta de armazenamento, SAS, credencial da entidade de serviço) no Azure KeyVault ou em um serviço equivalente.", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", - "service": "Azure Storage", + "ammp": true, + "checklist": "Azure Landing Zone Review", + "guid": "984a859c-773e-47d2-9162-3a765a917e1f", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", + "service": "Entra", "severity": "Alto", - "text": "Considere armazenar cadeias de conexão no Cofre de Chaves do Azure (em cenários em que identidades gerenciadas não são possíveis)", + "text": "Implemente um acesso de emergência ou contas de emergência para evitar o bloqueio de conta em todo o locatário. A MFA será ativada por padrão para todos os usuários em outubro de 2024. Recomendamos atualizar essas contas para usar a chave de acesso (FIDO2) ou configurar a autenticação baseada em certificado para MFA. ", + "training": "https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access#exclude-at-least-one-account-from-conditional-access-policies", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Use tempos de expiração de curto prazo em um SAS de serviço SAS ad hoc ou SAS de conta. Dessa forma, mesmo que um SAS seja comprometido, ele é válido apenas por um curto período de tempo. Essa prática é especialmente importante se você não puder fazer referência a uma política de acesso armazenado. Os tempos de expiração de curto prazo também limitam a quantidade de dados que podem ser gravados em um blob, limitando o tempo disponível para carregar nele.", - "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", - "severity": "Alto", - "text": "Esforce-se por curtos períodos de validade para SAS ad-hoc", + "checklist": "Azure Landing Zone Review", + "guid": "35037e68-9349-4c15-b371-228514f4cdff", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", + "service": "Entra", + "severity": "Média", + "text": "Não use contas sincronizadas locais para atribuições de função de ID do Microsoft Entra, a menos que você tenha um cenário que exija isso especificamente.", + "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Ao criar um SAS, seja o mais específico e restritivo possível. Prefira um SAS para um único recurso e operação em vez de um SAS que dá acesso muito mais amplo.", - "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", + "checklist": "Azure Landing Zone Review", + "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", + "service": "Entra", "severity": "Média", - "text": "Aplicar um escopo restrito a uma SAS", + "text": "Ao usar o Proxy de Aplicativo de ID do Microsoft Entra para fornecer acesso de usuários remotos a aplicativos, gerencie-o como um recurso da plataforma, pois você só pode ter uma instância por locatário.", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Uma SAS pode incluir parâmetros nos quais endereços IP de cliente ou intervalos de endereços estão autorizados a solicitar um recurso usando a SAS. ", - "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", - "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", - "service": "Azure Storage", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "e8bbac75-7155-49ab-a153-e8908ae28c84", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", + "service": "VNet", "severity": "Média", - "text": "Considere a definição do escopo do SAS para um endereço IP de cliente específico, sempre que possível", + "text": "Use uma topologia de rede hub-and-spoke para cenários de rede que exigem flexibilidade máxima.", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Um SAS não pode restringir a quantidade de dados que um cliente carrega; Dado o modelo de precificação da quantidade de armazenamento ao longo do tempo, pode fazer sentido validar se os clientes carregaram conteúdo maliciosamente grande.", - "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", - "service": "Azure Storage", - "severity": "Baixo", - "text": "Considere verificar os dados carregados, depois que os clientes usaram um SAS para carregar um arquivo. ", - "waf": "Segurança" + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology", + "service": "VNet", + "severity": "Alto", + "text": "Implante serviços de rede compartilhados, incluindo gateways do ExpressRoute, gateways de VPN e Firewall do Azure ou NVAs de parceiros na rede virtual do hub central. Se necessário, implante também serviços DNS.", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "waf": "Custar" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Ao acessar o armazenamento de blob via SFTP usando uma 'conta de usuário local', os controles RBAC 'normais' não se aplicam. O acesso a blobs via NFS ou REST pode ser mais restritivo do que o acesso a SFTP. Infelizmente, no início de 2023, os usuários locais são a única forma de gerenciamento de identidade que atualmente é suportada para o ponto de extremidade SFTP", - "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", - "service": "Azure Storage", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "service": "VNet", "severity": "Alto", - "text": "SFTP: Limite a quantidade de 'usuários locais' para acesso SFTP e audite se o acesso é necessário ao longo do tempo.", + "text": "Use um plano de proteção de IP ou rede DDoS para todos os endereços IP públicos nas zonas de destino do aplicativo.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", - "service": "Azure Storage", + "arm-service": "Microsoft.Compute/virtualMachines", + "checklist": "Azure Landing Zone Review", + "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", + "service": "NVA", "severity": "Média", - "text": "SFTP: O ponto de extremidade SFTP não oferece suporte a ACLs do tipo POSIX.", - "waf": "Segurança" + "text": "Ao implantar tecnologias de rede de parceiros ou NVAs, siga as diretrizes do fornecedor do parceiro.", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "O armazenamento oferece suporte a CORS (Cross-Origin Resource Sharing), ou seja, um recurso HTTP que permite que aplicativos Web de um domínio diferente afrouxem a política de mesma origem. Ao habilitar o CORS, mantenha o CorsRules com o menor privilégio.", - "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", - "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", - "service": "Azure Storage", - "severity": "Alto", - "text": "Evite políticas CORS excessivamente amplas", + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "ce463dbb-bc8a-4c2a-aebc-92a43da1dae2", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", + "service": "ExpressRoute", + "severity": "Baixo", + "text": "Se você precisar de trânsito entre o ExpressRoute e os gateways de VPN em cenários hub e spoke, use o Servidor de Rota do Azure.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Os dados em repouso são sempre criptografados no lado do servidor e, além disso, também podem ser criptografados no lado do cliente. A criptografia do lado do servidor pode acontecer usando uma chave gerenciada por plataforma (padrão) ou uma chave gerenciada pelo cliente. A criptografia do lado do cliente pode acontecer fazendo com que o cliente forneça uma chave de criptografia/descriptografia por blob para o armazenamento do Azure ou manipulando completamente a criptografia no lado do cliente. portanto, não depende do Armazenamento do Azure para garantias de confidencialidade.", - "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", - "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", - "service": "Azure Storage", - "severity": "Alto", - "text": "Determine como os dados em repouso devem ser criptografados. Entenda o modelo de thread para dados.", + "arm-service": "Microsoft.Network/virtualHubs", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", + "guid": "91b9d7d5-91e1-4dcb-8f1f-fa7e465646cc", + "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", + "service": "ARS", + "severity": "Baixo", + "text": "Se estiver usando o Servidor de Roteamento, use um prefixo /27 para a sub-rede do Servidor de Roteamento.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", - "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", - "service": "Azure Storage", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "cc881471-607c-41cc-a0e6-14658dd558f9", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", + "service": "VNet", "severity": "Média", - "text": "Determine qual/se a criptografia de plataforma deve ser usada.", - "waf": "Segurança" + "text": "Para arquiteturas de rede com várias topologias hub-and-spoke em regiões do Azure, use emparelhamentos de rede virtual global entre as VNets do hub para conectar as regiões entre si.", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", + "waf": "Desempenho" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", - "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", - "service": "Azure Storage", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", + "service": "VNet", "severity": "Média", - "text": "Determine qual/se a criptografia do lado do cliente deve ser usada.", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "Aproveite o Resource Graph Explorer (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) para localizar contas de armazenamento que permitem acesso anônimo a blobs.", - "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", - "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", - "service": "Azure Storage", - "severity": "Alto", - "text": "Considere se o acesso de blob público é necessário ou se pode ser desabilitado para determinadas contas de armazenamento. ", - "waf": "Segurança" + "text": "Use o Azure Monitor para Redes para monitorar o estado de ponta a ponta das redes no Azure.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "ac1d6380-f866-4bbd-a9b4-b1ee5d7908b8", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#availability-zones", - "service": "IoT", - "severity": "Alto", - "text": "Aproveitar zonas de disponibilidade, se aplicável regionalmente (isso é habilitado automaticamente)", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant", + "guid": "0e7c28ec-9366-4572-83b0-f4664b1d944a", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", + "service": "VNet", + "severity": "Média", + "text": "Se você tiver mais de 400 redes spoke em uma região, implante um hub adicional para ignorar os limites de emparelhamento VNet (500) e o número máximo de prefixos que podem ser anunciados por meio do ExpressRoute (1000).", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "35f651e8-0124-4ef7-8c57-658e38609e6e", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", - "service": "IoT", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant", + "guid": "3d457936-e9b7-41eb-bdff-314b26450b12", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", + "service": "VNet", "severity": "Média", - "text": "Esteja ciente dos failovers iniciados pela Microsoft. Eles são exercidos pela Microsoft em raras situações para fazer failover de todos os hubs IoT de uma região afetada para a região geo-emparelhada correspondente.", + "text": "Limite o número de rotas por tabela de rotas a 400.", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "4ed3e490-dc06-4a1e-b467-5d0239d85540", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#cross-region-dr", - "service": "IoT", + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)", + "guid": "c76cb5a2-abe2-11ed-afa1-0242ac120002", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", + "service": "VNet", "severity": "Alto", - "text": "Considere uma estratégia de DR entre regiões para cargas de trabalho críticas", + "text": "Use a configuração 'Permitir tráfego para rede virtual remota' ao configurar emparelhamentos VNet.", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "a11ecab0-db47-46f7-9aa7-17764e7e45a1", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", - "service": "IoT", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)", + "guid": "9dcd6250-9c4a-4382-aa9b-5b84c64fc1fe", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", + "service": "Load Balancers", "severity": "Alto", - "text": "Saiba como acionar um failover manual.", + "text": "Use o SKU do Standard Load Balancer com uma implantação com redundância de zona, a seleção do SKU Standard Load Balancer aumenta a confiabilidade por meio de zonas de disponibilidade e resiliência de zona, garantindo que as implantações resistam a falhas de zona e região. Ao contrário do Basic, ele oferece suporte ao balanceamento de carga global e oferece um SLA.", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "f9db8dfb-1194-460b-aedd-34dd6a69db22", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#failback", - "service": "IoT", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))", + "guid": "48682fb1-1e86-4458-a686-518ebd47393d", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", + "service": "Load Balancers", "severity": "Alto", - "text": "Saiba como fazer failback após um failover.", + "text": "Verifique se os pools de back-end do balanceador de carga contêm pelo menos duas instâncias, a implantação de Azure Load Balancers com pelo menos duas instâncias no back-end evita um único ponto de falha e dá suporte à escalabilidade.", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "7bc1c396-2461-4698-b57f-30ca69525252", - "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/considerations/regions", - "service": "VNet", + "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-macsec", + "service": "ExpressRoute", "severity": "Média", - "text": "Implante seus recursos de conectividade de zona de destino do Azure em várias regiões, para que você possa dar suporte rapidamente a zonas de destino de aplicativos de várias regiões e cenários de recuperação de desastre.", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "Fiabilidade" + "text": "Quando você estiver usando o ExpressRoute Direct, configure o MACsec para criptografar o tráfego no nível da camada dois entre os roteadores da organização e o MSEE. O diagrama mostra essa criptografia no fluxo.", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "Segurança" }, { + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "70c15989-c726-42c7-b0d3-24b7375b9201", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/considerations-recommendations", - "service": "Entra", + "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", + "link": "https://learn.microsoft.com/azure/vpn-gateway/site-to-site-vpn-private-peering", + "service": "ExpressRoute", "severity": "Média", - "text": "Use um locatário do Entra para gerenciar seus recursos do Azure, a menos que você tenha um requisito regulatório ou comercial claro para multilocatários.", - "training": "https://learn.microsoft.com/training/modules/deploy-resources-scopes-bicep/2-understand-deployment-scopes", - "waf": "Operações" + "text": "Para cenários em que o MACsec não é uma opção (por exemplo, não usando o ExpressRoute Direct), use um gateway de VPN para estabelecer túneis IPsec no emparelhamento privado do ExpressRoute.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" }, { + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "6309957b-821a-43d1-b9d9-7fcf1802b747", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", - "service": "Entra", - "severity": "Baixo", - "text": "Use a abordagem de Automação Multilocatário para gerenciar seus locatários de ID do Microsoft Entra.", - "training": "https://learn.microsoft.com/entra/architecture/multi-tenant-user-management-introduction/", - "waf": "Operações" + "guid": "558fd772-49b8-4211-82df-27ee412e7f98", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "service": "ExpressRoute", + "severity": "Alto", + "text": "Verifique se nenhum espaço de endereço IP sobreposto entre regiões do Azure e locais é usado.", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "Segurança" }, { + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "78e11934-499a-45ed-8ef7-aae5578f0ecf", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", - "service": "Entra", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr", + "guid": "3f630472-2dd6-49c5-a5c2-622f54b69bad", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "service": "VNet", + "severity": "Média", + "text": "Use endereços IP dos intervalos de alocação de endereços para Internets privadas (RFC 1918).", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant", + "guid": "33aad5e8-c68e-41d7-9667-313b4f5664b5", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "service": "VNet", "severity": "Alto", - "text": "Use o Azure Lighthouse para gerenciamento de vários locatários com as mesmas IDs.", - "training": "https://learn.microsoft.com/azure/lighthouse/concepts/cross-tenant-management-experience", - "waf": "Operações" + "text": "Certifique-se de que o espaço de endereço IP não seja desperdiçado, não crie redes virtuais desnecessariamente grandes (por exemplo, /16).", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "Desempenho" }, { + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "5d82e6df-6f61-42f2-82e2-3132d293be3d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "service": "Entra", + "guid": "f348ef25-4c27-4d42-b8bb-ac7571559ab9", + "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", + "service": "VNet", "severity": "Alto", - "text": "Se você conceder a um parceiro acesso para administrar seu locatário, use o Azure Lighthouse.", - "training": "https://learn.microsoft.com/azure/lighthouse/how-to/onboard-customer", - "waf": "Custar" + "text": "Não use intervalos de endereços IP sobrepostos para sites de produção e recuperação de desastres.", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Fiabilidade" }, { "checklist": "Azure Landing Zone Review", - "guid": "348ef254-c27d-442e-abba-c7571559ab91", - "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", - "service": "Entra", + "graph": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)", + "guid": "0c47f486-656d-4699-8c30-edef5b8a93c4", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone", + "service": "Public IP Addresses", "severity": "Alto", - "text": "Aplique um modelo RBAC que se alinhe ao seu modelo operacional de nuvem. Escopo e Atribuição entre Grupos de Gerenciamento e Assinaturas.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Segurança" + "text": "Use SKU Standard e IPs com redundância de zona quando aplicável, os endereços IP públicos no Azure podem ser de SKU padrão, disponíveis como não zonal, zonal ou com redundância de zona. Os IPs com redundância de zona podem ser acessados em todas as zonas, resistindo a qualquer falha de zona única, fornecendo assim maior resiliência. ", + "training": "https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing", + "waf": "Fiabilidade" }, { + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "12e7f983-f630-4472-8dd6-9c5b5c2622f5", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", - "service": "Entra", + "guid": "153e8908-ae28-4c84-a33b-6b7808b9fe5c", + "link": "https://learn.microsoft.com/azure/dns/private-dns-getstarted-portal", + "service": "DNS", "severity": "Média", - "text": "Use apenas o tipo de autenticação Conta corporativa ou de estudante para todos os tipos de conta. Evite usar a conta da Microsoft", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", - "waf": "Segurança" + "text": "Para ambientes em que a resolução de nomes no Azure é tudo o que é necessário, use o DNS Privado do Azure para resolução com uma zona delegada para resolução de nomes (como 'azure.contoso.com').", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Operações" }, { + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", - "service": "Entra", + "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", + "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", + "service": "DNS", "severity": "Média", - "text": "Use apenas grupos para atribuir permissões. Adicione grupos locais ao grupo Somente ID do Entra se um sistema de gerenciamento de grupo já estiver em vigor.", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", + "text": "Para ambientes em que a resolução de nomes no Azure e no local é necessária e não há nenhum serviço DNS corporativo existente, como o Active Directory, use o Resolvedor Privado de DNS do Azure para rotear solicitações de DNS para o Azure ou para servidores DNS locais.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", "waf": "Segurança" }, { + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", - "service": "Entra", - "severity": "Alto", - "text": "Imponha políticas de Acesso Condicional da ID do Microsoft Entra para qualquer usuário com direitos a ambientes do Azure.", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", - "waf": "Segurança" + "guid": "1e6a83de-5de3-42c1-a924-81607d5d1e4e", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", + "service": "DNS", + "severity": "Baixo", + "text": "Cargas de trabalho especiais que exigem e implantam seu próprio DNS (como o Red Hat OpenShift) devem usar sua solução de DNS preferida.", + "training": "https://learn.microsoft.com/training/courses/az-700t00", + "waf": "Operações" }, { + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", - "service": "Entra", + "guid": "614658d3-558f-4d77-849b-821112df27ee", + "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", + "service": "DNS", "severity": "Alto", - "text": "Imponha a autenticação multifator para qualquer usuário com direitos aos ambientes do Azure.", - "training": "https://learn.microsoft.com/entra/identity/authentication/concept-mandatory-multifactor-authentication", - "waf": "Segurança" + "text": "Habilite o registro automático para o DNS do Azure para gerenciar automaticamente o ciclo de vida dos registros DNS para as máquinas virtuais implantadas em uma rede virtual.", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Operações" }, { + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "14658d35-58fd-4772-99b8-21112df27ee4", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", - "service": "Entra", + "guid": "18c80eb0-582a-4198-bf5c-d8800b2d263b", + "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale#private-link-and-dns-integration-in-hub-and-spoke-network-architectures", + "service": "DNS", "severity": "Média", - "text": "Imponha o Microsoft Entra ID Privileged Identity Management (PIM) para estabelecer acesso permanente zero e privilégios mínimos.", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", - "waf": "Segurança" + "text": "Implementar um plano para gerenciar a resolução de DNS entre várias regiões do Azure e quando os serviços fazem failover para outra região", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "Fiabilidade" }, { + "arm-service": "microsoft.network/bastionHosts", "checklist": "Azure Landing Zone Review", - "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", - "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", - "service": "Entra", + "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", + "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", + "service": "Bastion", "severity": "Média", - "text": "Se estiver planejando alternar dos Serviços de Domínio Active Directory para os serviços de domínio Entra, avalie a compatibilidade de todas as cargas de trabalho.", - "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", + "text": "Use o Azure Bastion para se conectar com segurança à sua rede.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", "waf": "Segurança" }, { + "arm-service": "microsoft.network/bastionHosts", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.aad/domainservices' | extend replicaSets = properties.replicaSets | where array_length(replicaSets) < 2 | project name=name, id=id, tags=tags, param1=strcat('replicaSetLocation:', replicaSets[0].location)", - "guid": "0dd4e625-9c4b-4a56-b54a-4357bac12761", - "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", - "service": "Entra", - "severity": "Média", - "text": "Ao usar o Microsoft Entra Domain Services, use conjuntos de réplicas. Os conjuntos de réplicas melhorarão a resiliência do domínio gerenciado e permitirão que você implante em regiões adicionais. ", - "training": "https://learn.microsoft.com/training/modules/understand-azure-active-directory/6-examine-azure-domain-services", - "waf": "Fiabilidade" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", - "service": "Entra", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant", + "guid": "6eab9eb6-762b-485e-8ea8-15aa5dba0bd0", + "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", + "service": "Bastion", "severity": "Média", - "text": "Integre os logs de ID do Microsoft Entra com o Azure Monitor central da plataforma. O Azure Monitor permite uma única fonte de verdade sobre dados de log e monitoramento no Azure, oferecendo às organizações opções nativas de nuvem para atender aos requisitos de coleta e retenção de logs.", - "training": "https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs", + "text": "Use o Azure Bastion em uma sub-rede /26 ou maior.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", "waf": "Segurança" }, { - "ammp": true, + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "984a859c-773e-47d2-9162-3a765a917e1f", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", - "service": "Entra", - "severity": "Alto", - "text": "Implemente um acesso de emergência ou contas de emergência para evitar o bloqueio de conta em todo o locatário. A MFA será ativada por padrão para todos os usuários em outubro de 2024. Recomendamos atualizar essas contas para usar a chave de acesso (FIDO2) ou configurar a autenticação baseada em certificado para MFA. ", - "training": "https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access#exclude-at-least-one-account-from-conditional-access-policies", + "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", + "service": "WAF", + "severity": "Média", + "text": "Use as políticas do Azure Front Door e do WAF para fornecer proteção global entre regiões do Azure para conexões HTTP/S de entrada para uma zona de destino.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Segurança" }, { + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "35037e68-9349-4c15-b371-228514f4cdff", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", - "service": "Entra", - "severity": "Média", - "text": "Não use contas sincronizadas locais para atribuições de função de ID do Microsoft Entra, a menos que você tenha um cenário que exija isso especificamente.", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "WAF", + "severity": "Baixo", + "text": "Ao usar o Azure Front Door e o Gateway de Aplicativo do Azure para ajudar a proteger aplicativos HTTP/S, use políticas WAF no Azure Front Door. Bloqueie o Gateway de Aplicativo do Azure para receber tráfego somente do Azure Front Door.", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", "waf": "Segurança" }, { + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", - "service": "Entra", - "severity": "Média", - "text": "Ao usar o Proxy de Aplicativo de ID do Microsoft Entra para fornecer acesso de usuários remotos a aplicativos, gerencie-o como um recurso da plataforma, pois você só pode ter uma instância por locatário.", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "WAF", + "severity": "Alto", + "text": "Quando WAFs e outros proxies reversos forem necessários para conexões HTTP/S de entrada, implante-os em uma rede virtual de zona de destino e junto com os aplicativos que eles estão protegendo e expondo à Internet.", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "Segurança" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "e8bbac75-7155-49ab-a153-e8908ae28c84", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", + "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", "service": "VNet", - "severity": "Média", - "text": "Use uma topologia de rede hub-and-spoke para cenários de rede que exigem flexibilidade máxima.", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "severity": "Alto", + "text": "Use os planos de Rede ou Proteção de IP do Azure contra DDoS para ajudar a proteger os pontos de extremidade de endereços IP públicos nas redes virtuais.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology", + "guid": "b034c01e-110b-463a-b36e-e3346e57f225", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/default-outbound-access", "service": "VNet", "severity": "Alto", - "text": "Implante serviços de rede compartilhados, incluindo gateways do ExpressRoute, gateways de VPN e Firewall do Azure ou NVAs de parceiros na rede virtual do hub central. Se necessário, implante também serviços DNS.", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "Custar" + "text": "Planeje como gerenciar a configuração e a estratégia de tráfego de saída da rede antes da próxima alteração significativa. Em 30 de setembro de 2025, o acesso de saída padrão para novas implantações será desativado e somente configurações de acesso explícito serão permitidas.", + "training": "https://learn.microsoft.com/training/modules/configure-virtual-networks/", + "waf": "Fiabilidade" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "guid": "b1c82a3f-2320-4dfa-8972-7ae4823c8930", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", "service": "VNet", "severity": "Alto", - "text": "Use um plano de proteção de IP ou rede DDoS para todos os endereços IP públicos nas zonas de destino do aplicativo.", + "text": "Adicione configurações de diagnóstico para salvar logs relacionados a DDoS para todos os endereços IP públicos protegidos (IP DDoS ou Proteção de Rede).", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Compute/virtualMachines", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", - "service": "NVA", - "severity": "Média", - "text": "Ao implantar tecnologias de rede de parceiros ou NVAs, siga as diretrizes do fornecedor do parceiro.", - "waf": "Fiabilidade" + "guid": "3c5a808d-c695-4c14-a63c-c7ab7a510e41", + "link": "https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies#corp", + "service": "Policy", + "severity": "Alto", + "text": "Verifique se há uma atribuição de política para negar endereços IP públicos diretamente vinculados a máquinas virtuais. Use exclusões se IPs públicos forem necessários em VMs específicas.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "Segurança" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "ce463dbb-bc8a-4c2a-aebc-92a43da1dae2", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", + "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", "service": "ExpressRoute", - "severity": "Baixo", - "text": "Se você precisar de trânsito entre o ExpressRoute e os gateways de VPN em cenários hub e spoke, use o Servidor de Rota do Azure.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", - "waf": "Segurança" + "severity": "Média", + "text": "Use o ExpressRoute como a conexão principal com o Azure. Use VPNs como fonte de conectividade de backup.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Desempenho" }, { - "arm-service": "Microsoft.Network/virtualHubs", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", - "guid": "91b9d7d5-91e1-4dcb-8f1f-fa7e465646cc", - "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", - "service": "ARS", - "severity": "Baixo", - "text": "Se estiver usando o Servidor de Roteamento, use um prefixo /27 para a sub-rede do Servidor de Roteamento.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", - "waf": "Segurança" + "description": "Você pode usar o prefixo AS-path e pesos de conexão para influenciar o tráfego do Azure para o local e toda a gama de atributos BGP em seus próprios roteadores para influenciar o tráfego do local para o Azure.", + "guid": "f29812b2-363c-4efe-879b-599de0d5973c", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", + "service": "ExpressRoute", + "severity": "Média", + "text": "Ao usar vários circuitos do ExpressRoute ou vários locais locais, use atributos BGP para otimizar o roteamento.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "cc881471-607c-41cc-a0e6-14658dd558f9", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", - "service": "VNet", + "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant", + "guid": "d4cd21b0-8813-47f5-b6c4-cfd3e504547c", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku", + "service": "ExpressRoute", "severity": "Média", - "text": "Para arquiteturas de rede com várias topologias hub-and-spoke em regiões do Azure, use emparelhamentos de rede virtual global entre as VNets do hub para conectar as regiões entre si.", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", + "text": "Selecione o SKU correto para os gateways ExpressRoute/VPN com base nos requisitos de largura de banda e desempenho.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Desempenho" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", - "service": "VNet", - "severity": "Média", - "text": "Use o Azure Monitor para Redes para monitorar o estado de ponta a ponta das redes no Azure.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", - "waf": "Operações" + "graph": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant", + "guid": "7025b442-f6e9-4af6-b11f-c9574916016f", + "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", + "service": "ExpressRoute", + "severity": "Alto", + "text": "Verifique se você está usando circuitos do ExpressRoute de dados ilimitados somente se atingir a largura de banda que justifica seu custo.", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "Custar" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant", - "guid": "0e7c28ec-9366-4572-83b0-f4664b1d944a", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", - "service": "VNet", + "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id", + "guid": "f4e7926a-ec35-476e-a412-5dd17136bd62", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", + "service": "ExpressRoute", + "severity": "Alto", + "text": "Aproveite o SKU local do ExpressRoute para reduzir o custo de seus circuitos, se o local de emparelhamento de circuito der suporte às regiões do Azure para o SKU Local.", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "Custar" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant", + "guid": "2447ec66-138a-4720-8f1c-e16ed301d6e8", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways", + "service": "ExpressRoute", "severity": "Média", - "text": "Se você tiver mais de 400 redes spoke em uma região, implante um hub adicional para ignorar os limites de emparelhamento VNet (500) e o número máximo de prefixos que podem ser anunciados por meio do ExpressRoute (1000).", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "text": "Implante um gateway do ExpressRoute com redundância de zona nas regiões do Azure com suporte.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant", - "guid": "3d457936-e9b7-41eb-bdff-314b26450b12", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", - "service": "VNet", + "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", + "service": "ExpressRoute", "severity": "Média", - "text": "Limite o número de rotas por tabela de rotas a 400.", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "Fiabilidade" + "text": "Para cenários que exigem largura de banda superior a 10 Gbps ou portas dedicadas de 10/100 Gbps, use o ExpressRoute Direct.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Desempenho" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)", - "guid": "c76cb5a2-abe2-11ed-afa1-0242ac120002", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", - "service": "VNet", - "severity": "Alto", - "text": "Use a configuração 'Permitir tráfego para rede virtual remota' ao configurar emparelhamentos VNet.", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "Fiabilidade" + "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", + "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", + "service": "ExpressRoute", + "severity": "Média", + "text": "Quando a baixa latência for necessária ou a taxa de transferência do local para o Azure precisar ser maior que 10 Gbps, habilite o FastPath para ignorar o gateway do ExpressRoute do caminho de dados.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Desempenho" }, { + "arm-service": "microsoft.network/virtualNetworkGateways", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)", - "guid": "9dcd6250-9c4a-4382-aa9b-5b84c64fc1fe", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", - "service": "Load Balancers", - "severity": "Alto", - "text": "Use o SKU do Standard Load Balancer com uma implantação com redundância de zona, a seleção do SKU Standard Load Balancer aumenta a confiabilidade por meio de zonas de disponibilidade e resiliência de zona, garantindo que as implantações resistam a falhas de zona e região. Ao contrário do Basic, ele oferece suporte ao balanceamento de carga global e oferece um SLA.", + "graph": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant", + "guid": "4d873974-8b66-42d6-b15f-512a65498f6d", + "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", + "service": "VPN", + "severity": "Média", + "text": "Use gateways de VPN com redundância de zona para conectar branches ou locais remotos ao Azure (quando disponível).", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", "waf": "Fiabilidade" }, { + "arm-service": "microsoft.network/virtualNetworkGateways", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))", - "guid": "48682fb1-1e86-4458-a686-518ebd47393d", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", - "service": "Load Balancers", - "severity": "Alto", - "text": "Verifique se os pools de back-end do balanceador de carga contêm pelo menos duas instâncias, a implantação de Azure Load Balancers com pelo menos duas instâncias no back-end evita um único ponto de falha e dá suporte à escalabilidade.", + "guid": "45866df8-cf85-4ca9-bbe2-65ec1478919e", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", + "service": "VPN", + "severity": "Média", + "text": "Use dispositivos VPN redundantes locais (ativo/ativo ou ativo/passivo).", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", "waf": "Fiabilidade" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-macsec", + "guid": "718cb437-b060-2589-8856-2e93a5c6633b", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", "service": "ExpressRoute", - "severity": "Média", - "text": "Quando você estiver usando o ExpressRoute Direct, configure o MACsec para criptografar o tráfego no nível da camada dois entre os roteadores da organização e o MSEE. O diagrama mostra essa criptografia no fluxo.", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "Segurança" + "severity": "Alto", + "text": "Se estiver usando o ExpressRoute Direct, considere usar circuitos locais do ExpressRoute para as regiões locais do Azure para economizar custos.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Custar" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", - "link": "https://learn.microsoft.com/azure/vpn-gateway/site-to-site-vpn-private-peering", + "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", + "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", "service": "ExpressRoute", "severity": "Média", - "text": "Para cenários em que o MACsec não é uma opção (por exemplo, não usando o ExpressRoute Direct), use um gateway de VPN para estabelecer túneis IPsec no emparelhamento privado do ExpressRoute.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "text": "Quando o isolamento de tráfego ou a largura de banda dedicada for necessária, como para separar ambientes de produção e não produção, use circuitos diferentes do ExpressRoute. Ele ajudará você a garantir domínios de roteamento isolados e aliviar os riscos de vizinhos barulhentos.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "Segurança" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "558fd772-49b8-4211-82df-27ee412e7f98", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "guid": "b30e38c3-f298-412b-8363-cefe179b599d", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", "service": "ExpressRoute", - "severity": "Alto", - "text": "Verifique se nenhum espaço de endereço IP sobreposto entre regiões do Azure e locais é usado.", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Segurança" + "severity": "Média", + "text": "Monitore a disponibilidade e a utilização do ExpressRoute usando o Express Route Insights interno.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr", - "guid": "3f630472-2dd6-49c5-a5c2-622f54b69bad", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "service": "VNet", + "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", + "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", + "service": "ExpressRoute", "severity": "Média", - "text": "Use endereços IP dos intervalos de alocação de endereços para Internets privadas (RFC 1918).", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Segurança" + "text": "Use o Monitor da Conexão para monitoramento de conectividade em toda a rede, especialmente entre o local e o Azure.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant", - "guid": "33aad5e8-c68e-41d7-9667-313b4f5664b5", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "service": "VNet", - "severity": "Alto", - "text": "Certifique-se de que o espaço de endereço IP não seja desperdiçado, não crie redes virtuais desnecessariamente grandes (por exemplo, /16).", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "Desempenho" + "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)", + "guid": "e0d5973c-d4cd-421b-8881-37f5e6c4cfd3", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution", + "service": "ExpressRoute", + "severity": "Média", + "text": "Use circuitos do ExpressRoute de diferentes locais de emparelhamento para redundância.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "f348ef25-4c27-4d42-b8bb-ac7571559ab9", - "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", - "service": "VNet", - "severity": "Alto", - "text": "Não use intervalos de endereços IP sobrepostos para sites de produção e recuperação de desastres.", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "guid": "cf3fe65c-fec0-495a-8edc-9675200f2add", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager", + "service": "ExpressRoute", + "severity": "Média", + "text": "Use a VPN site a site como failover do ExpressRoute, se estiver usando apenas um único circuito do ExpressRoute.", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", "waf": "Fiabilidade" }, { + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)", - "guid": "0c47f486-656d-4699-8c30-edef5b8a93c4", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone", - "service": "Public IP Addresses", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))", + "guid": "72105cc8-aaea-4ee1-8c7a-ad25977afcaf", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub", + "service": "ExpressRoute", "severity": "Alto", - "text": "Use SKU Standard e IPs com redundância de zona quando aplicável, os endereços IP públicos no Azure podem ser de SKU padrão, disponíveis como não zonal, zonal ou com redundância de zona. Os IPs com redundância de zona podem ser acessados em todas as zonas, resistindo a qualquer falha de zona única, fornecendo assim maior resiliência. ", - "training": "https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing", + "text": "Se você estiver usando uma tabela de rotas no GatewaySubnet, certifique-se de que as rotas de gateway sejam propagadas.", "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/dnsZones", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "153e8908-ae28-4c84-a33b-6b7808b9fe5c", - "link": "https://learn.microsoft.com/azure/dns/private-dns-getstarted-portal", - "service": "DNS", - "severity": "Média", - "text": "Para ambientes em que a resolução de nomes no Azure é tudo o que é necessário, use o DNS Privado do Azure para resolução com uma zona delegada para resolução de nomes (como 'azure.contoso.com').", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "Operações" + "guid": "d581a947-69a2-4783-942e-9df3664324c8", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", + "service": "ExpressRoute", + "severity": "Alto", + "text": "Se estiver usando o ExpressRoute, o roteamento local deverá ser dinâmico: no caso de uma falha de conexão, ele deverá convergir para a conexão restante do circuito. A carga deve ser compartilhada entre ambas as conexões, idealmente como ativa/ativa, embora ativa/passiva também seja suportada.", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/dnsZones", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", - "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", - "service": "DNS", + "guid": "b258f058-b9f6-46cd-b28d-990106f0c3f8", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute", + "service": "ExpressRoute", "severity": "Média", - "text": "Para ambientes em que a resolução de nomes no Azure e no local é necessária e não há nenhum serviço DNS corporativo existente, como o Active Directory, use o Resolvedor Privado de DNS do Azure para rotear solicitações de DNS para o Azure ou para servidores DNS locais.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", - "waf": "Segurança" + "text": "Verifique se os dois links físicos do circuito do ExpressRoute estão conectados a dois dispositivos de borda distintos em sua rede.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/dnsZones", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "1e6a83de-5de3-42c1-a924-81607d5d1e4e", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", - "service": "DNS", - "severity": "Baixo", - "text": "Cargas de trabalho especiais que exigem e implantam seu próprio DNS (como o Red Hat OpenShift) devem usar sua solução de DNS preferida.", - "training": "https://learn.microsoft.com/training/courses/az-700t00", - "waf": "Operações" + "guid": "fe2a1b53-6fbd-4c67-b58a-85d7c7a0afcb", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-bfd", + "service": "ExpressRoute", + "severity": "Média", + "text": "Certifique-se de que a Detecção de Encaminhamento Bidirecional (BFD) esteja habilitada e configurada em dispositivos de roteamento de borda do cliente ou provedor.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/dnsZones", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "614658d3-558f-4d77-849b-821112df27ee", - "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", - "service": "DNS", + "guid": "669b215a-ce43-4371-8f6f-11047f6490f1", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", + "service": "ExpressRoute", "severity": "Alto", - "text": "Habilite o registro automático para o DNS do Azure para gerenciar automaticamente o ciclo de vida dos registros DNS para as máquinas virtuais implantadas em uma rede virtual.", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "Operações" + "text": "Conecte o Gateway do ExpressRoute a dois ou mais circuitos de diferentes locais de emparelhamento para maior resiliência.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/dnsZones", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "18c80eb0-582a-4198-bf5c-d8800b2d263b", - "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale#private-link-and-dns-integration-in-hub-and-spoke-network-architectures", - "service": "DNS", + "guid": "3f79ed00-203b-4c95-9efd-691505f5a1f9", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-howto-setup-alerts-virtual-network-gateway-log", + "service": "ExpressRoute", "severity": "Média", - "text": "Implementar um plano para gerenciar a resolução de DNS entre várias regiões do Azure e quando os serviços fazem failover para outra região", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "Fiabilidade" + "text": "Configure logs de diagnóstico e alertas para o gateway de rede virtual do ExpressRoute.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/bastionHosts", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", - "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", - "service": "Bastion", + "guid": "5234c93f-b651-41dd-80c1-234177b91ced", + "link": "https://learn.microsoft.com/azure/expressroute/virtual-network-connectivity-guidance", + "service": "ExpressRoute", "severity": "Média", - "text": "Use o Azure Bastion para se conectar com segurança à sua rede.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", - "waf": "Segurança" + "text": "Não use circuitos do ExpressRoute para comunicação VNet para VNet.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "Desempenho" }, { - "arm-service": "microsoft.network/bastionHosts", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant", - "guid": "6eab9eb6-762b-485e-8ea8-15aa5dba0bd0", - "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", - "service": "Bastion", - "severity": "Média", - "text": "Use o Azure Bastion em uma sub-rede /26 ou maior.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", + "guid": "8ac6a9e0-1e6a-483d-b5de-32c199248160", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", + "service": "N/A", + "severity": "Baixo", + "text": "Não envie o tráfego do Azure para locais híbridos para inspeção. Em vez disso, siga o princípio \"o tráfego no Azure permanece no Azure\" para que a comunicação entre os recursos no Azure ocorra por meio da rede de backbone da Microsoft.", + "waf": "Desempenho" + }, + { + "arm-service": "Microsoft.Network/azureFirewalls", + "checklist": "Azure Landing Zone Review", + "guid": "e6c4cfd3-e504-4547-a244-7ec66138a720", + "link": "https://learn.microsoft.com/azure/firewall/overview", + "service": "Firewall", + "severity": "Alto", + "text": "Use o Firewall do Azure para controlar o tráfego de saída do Azure para a Internet, conexões de entrada não HTTP/S e filtragem de tráfego Leste/Oeste (se a organização exigir).", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", - "service": "WAF", + "guid": "5a4b1511-e43a-458a-ac22-99c4d7b57d0c", + "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", + "service": "Firewall", "severity": "Média", - "text": "Use as políticas do Azure Front Door e do WAF para fornecer proteção global entre regiões do Azure para conexões HTTP/S de entrada para uma zona de destino.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "text": "Crie uma política global de Firewall do Azure para controlar a postura de segurança em todo o ambiente de rede global e atribua-a a todas as instâncias do Firewall do Azure. Permita que políticas granulares atendam aos requisitos de regiões específicas delegando políticas de firewall incrementais às equipes de segurança locais por meio do controle de acesso baseado em função do Azure.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "service": "WAF", + "guid": "655562f2-b3e4-4563-a4d8-739748b662d6", + "link": "https://learn.microsoft.com/azure/firewall-manager/deploy-trusted-security-partner", + "service": "Firewall", "severity": "Baixo", - "text": "Ao usar o Azure Front Door e o Gateway de Aplicativo do Azure para ajudar a proteger aplicativos HTTP/S, use políticas WAF no Azure Front Door. Bloqueie o Gateway de Aplicativo do Azure para receber tráfego somente do Azure Front Door.", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "text": "Configure provedores de segurança SaaS de parceiros compatíveis no Firewall Manager se a organização quiser usar essas soluções para ajudar a proteger as conexões de saída.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "service": "WAF", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant", + "guid": "14d99880-2f88-47e8-a134-62a7d85c94af", + "link": "https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules", + "service": "Firewall", "severity": "Alto", - "text": "Quando WAFs e outros proxies reversos forem necessários para conexões HTTP/S de entrada, implante-os em uma rede virtual de zona de destino e junto com os aplicativos que eles estão protegendo e expondo à Internet.", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "text": "Use regras de aplicativo para filtrar o tráfego de saída no nome do host de destino para protocolos com suporte. Use regras de rede baseadas em FQDN e Firewall do Azure com proxy DNS para filtrar o tráfego de saída para a Internet em outros protocolos.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", - "service": "VNet", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant", + "guid": "c10d51ef-f999-455d-bba0-5c90ece07447", + "link": "https://learn.microsoft.com/azure/firewall/premium-features", + "service": "Firewall", "severity": "Alto", - "text": "Use os planos de Rede ou Proteção de IP do Azure contra DDoS para ajudar a proteger os pontos de extremidade de endereços IP públicos nas redes virtuais.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "text": "Use o Firewall do Azure Premium para habilitar recursos de segurança adicionais.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-firewall/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "b034c01e-110b-463a-b36e-e3346e57f225", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/default-outbound-access", - "service": "VNet", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant", + "guid": "e9c8f584-6d5e-473b-8dc5-acc9fbaab4e3", + "link": "https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules", + "service": "Firewall", "severity": "Alto", - "text": "Planeje como gerenciar a configuração e a estratégia de tráfego de saída da rede antes da próxima alteração significativa. Em 30 de setembro de 2025, o acesso de saída padrão para novas implantações será desativado e somente configurações de acesso explícito serão permitidas.", - "training": "https://learn.microsoft.com/training/modules/configure-virtual-networks/", - "waf": "Fiabilidade" + "text": "Configure o modo de Inteligência contra Ameaças do Firewall do Azure como Alerta e Negação para proteção adicional.", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "b1c82a3f-2320-4dfa-8972-7ae4823c8930", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", - "service": "VNet", + "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant", + "guid": "b9d0dff5-bdd4-4cd8-88ed-5811610b2b2c", + "link": "https://learn.microsoft.com/azure/firewall/premium-features#idps", + "service": "Firewall", "severity": "Alto", - "text": "Adicione configurações de diagnóstico para salvar logs relacionados a DDoS para todos os endereços IP públicos protegidos (IP DDoS ou Proteção de Rede).", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "text": "Configure o modo IDPS do Firewall do Azure como Negar para proteção adicional.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-firewall/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "3c5a808d-c695-4c14-a63c-c7ab7a510e41", - "link": "https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies#corp", - "service": "Policy", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant", + "guid": "a3784907-9836-4271-aafc-93535f8ec08b", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", + "service": "Firewall", "severity": "Alto", - "text": "Verifique se há uma atribuição de política para negar endereços IP públicos diretamente vinculados a máquinas virtuais. Use exclusões se IPs públicos forem necessários em VMs específicas.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "text": "Para sub-redes em VNets não conectadas à WAN Virtual, anexe uma tabela de rotas para que o tráfego da Internet seja redirecionado para o Firewall do Azure ou uma Solução de Virtualização de Rede.", "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", - "service": "ExpressRoute", + "guid": "715d833d-4708-4527-90ac-1b142c7045ba", + "link": "https://learn.microsoft.com/azure/firewall/firewall-structured-logs", + "service": "Firewall", "severity": "Média", - "text": "Use o ExpressRoute como a conexão principal com o Azure. Use VPNs como fonte de conectividade de backup.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Desempenho" + "text": "Adicione configurações de diagnóstico para salvar logs, usando a tabela de destino Específico do Recurso, para todas as implantações do Firewall do Azure.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "description": "Você pode usar o prefixo AS-path e pesos de conexão para influenciar o tráfego do Azure para o local e toda a gama de atributos BGP em seus próprios roteadores para influenciar o tráfego do local para o Azure.", - "guid": "f29812b2-363c-4efe-879b-599de0d5973c", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", - "service": "ExpressRoute", - "severity": "Média", - "text": "Ao usar vários circuitos do ExpressRoute ou vários locais locais, use atributos BGP para otimizar o roteamento.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "guid": "e960fc6b-4ab2-4db6-9609-3745135f9ffa", + "link": "https://learn.microsoft.com/azure/firewall-manager/migrate-to-policy", + "service": "Firewall", + "severity": "Alto", + "text": "Migre das regras clássicas do Firewall do Azure (se houver) para a Política de Firewall.", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant", - "guid": "d4cd21b0-8813-47f5-b6c4-cfd3e504547c", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku", - "service": "ExpressRoute", - "severity": "Média", - "text": "Selecione o SKU correto para os gateways ExpressRoute/VPN com base nos requisitos de largura de banda e desempenho.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Desempenho" - }, - { - "arm-service": "microsoft.network/expressRouteCircuits", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant", - "guid": "7025b442-f6e9-4af6-b11f-c9574916016f", - "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", - "service": "ExpressRoute", - "severity": "Alto", - "text": "Verifique se você está usando circuitos do ExpressRoute de dados ilimitados somente se atingir a largura de banda que justifica seu custo.", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "Custar" - }, - { - "arm-service": "microsoft.network/expressRouteCircuits", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id", - "guid": "f4e7926a-ec35-476e-a412-5dd17136bd62", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", - "service": "ExpressRoute", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant", + "guid": "22d6419e-b627-4d95-9e7d-019fa759387f", + "link": "https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size", + "service": "Firewall", "severity": "Alto", - "text": "Aproveite o SKU local do ExpressRoute para reduzir o custo de seus circuitos, se o local de emparelhamento de circuito der suporte às regiões do Azure para o SKU Local.", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "Custar" + "text": "Use um prefixo /26 para suas sub-redes do Firewall do Azure.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-firewall/", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant", - "guid": "2447ec66-138a-4720-8f1c-e16ed301d6e8", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways", - "service": "ExpressRoute", + "guid": "828cec2e-af6c-40c2-8fa2-1b681ee63eb7", + "link": "https://learn.microsoft.com/azure/firewall-manager/rule-hierarchy", + "service": "Firewall", "severity": "Média", - "text": "Implante um gateway do ExpressRoute com redundância de zona nas regiões do Azure com suporte.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "text": "Organize as regras dentro da política de firewall em Grupos de Coleção de Regras e Coleções de Regras e com base em sua frequência de uso.", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-firewall-manager/", + "waf": "Desempenho" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", - "service": "ExpressRoute", + "guid": "0da83bb1-2f39-49af-b5c9-835fc455e3d1", + "link": "https://learn.microsoft.com/azure/firewall/ip-groups", + "service": "Firewall", "severity": "Média", - "text": "Para cenários que exigem largura de banda superior a 10 Gbps ou portas dedicadas de 10/100 Gbps, use o ExpressRoute Direct.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "text": "Use grupos de IP ou prefixos de IP para reduzir o número de regras de tabela de IP.", "waf": "Desempenho" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", - "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", - "service": "ExpressRoute", + "guid": "c44c6f0e-1642-4a61-a17b-0922f835c93a", + "link": "https://learn.microsoft.com/azure/firewall/tutorial-firewall-dnat", + "service": "Firewall", "severity": "Média", - "text": "Quando a baixa latência for necessária ou a taxa de transferência do local para o Azure precisar ser maior que 10 Gbps, habilite o FastPath para ignorar o gateway do ExpressRoute do caminho de dados.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "text": "Não use curingas como um IP de origem para DNATS, como * ou any, você deve especificar IPs de origem para DNATs de entrada.", + "training": "https://learn.microsoft.com/training/modules/introduction-to-azure-virtual-networks/", "waf": "Desempenho" }, { - "arm-service": "microsoft.network/virtualNetworkGateways", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant", - "guid": "4d873974-8b66-42d6-b15f-512a65498f6d", - "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", - "service": "VPN", + "guid": "7371dc21-251a-47a3-af14-6e01b9da4757", + "link": "https://learn.microsoft.com/azure/firewall/integrate-with-nat-gateway", + "service": "Firewall", "severity": "Média", - "text": "Use gateways de VPN com redundância de zona para conectar branches ou locais remotos ao Azure (quando disponível).", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", - "waf": "Fiabilidade" + "text": "Evite o esgotamento da porta SNAT monitorando o uso da porta SNAT, avaliando as configurações do NAT Gateway e garantindo um failover contínuo. Se a contagem de portas se aproximar do limite, é um sinal de que o esgotamento do SNAT pode ser iminente.", + "training": "https://learn.microsoft.com/training/modules/introduction-to-azure-virtual-networks/", + "waf": "Desempenho" }, { - "arm-service": "microsoft.network/virtualNetworkGateways", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "45866df8-cf85-4ca9-bbe2-65ec1478919e", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", - "service": "VPN", - "severity": "Média", - "text": "Use dispositivos VPN redundantes locais (ativo/ativo ou ativo/passivo).", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", - "waf": "Fiabilidade" + "guid": "346840b8-1064-496e-8396-4b1340172d52", + "link": "https://learn.microsoft.com/azure/firewall/premium-features#tls-inspection", + "service": "Firewall", + "severity": "Alto", + "text": "Se você estiver usando o Firewall do Azure Premium, habilite a Inspeção TLS.", + "waf": "Desempenho" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "718cb437-b060-2589-8856-2e93a5c6633b", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", - "service": "ExpressRoute", - "severity": "Alto", - "text": "Se estiver usando o ExpressRoute Direct, considere usar circuitos locais do ExpressRoute para as regiões locais do Azure para economizar custos.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Custar" + "guid": "39990a13-915c-45f9-a2d3-562d7d6c4b7c", + "link": "https://learn.microsoft.com/azure/firewall/premium-features#web-categories", + "service": "Firewall", + "severity": "Baixo", + "text": "Use categorias da Web para permitir ou negar o acesso de saída a tópicos específicos.", + "waf": "Desempenho" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", - "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", - "service": "ExpressRoute", + "guid": "6eff7e6c-6c4a-43d7-be3f-6641c2cb3d4a", + "link": "https://learn.microsoft.com/azure/architecture/example-scenario/gateway/application-gateway-before-azure-firewall", + "service": "Firewall", "severity": "Média", - "text": "Quando o isolamento de tráfego ou a largura de banda dedicada for necessária, como para separar ambientes de produção e não produção, use circuitos diferentes do ExpressRoute. Ele ajudará você a garantir domínios de roteamento isolados e aliviar os riscos de vizinhos barulhentos.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Segurança" + "text": "Como parte da inspeção TLS, planeje o recebimento de tráfego dos Gateways de Aplicativo do Azure para inspeção.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-application-gateway/", + "waf": "Desempenho" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "b30e38c3-f298-412b-8363-cefe179b599d", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", - "service": "ExpressRoute", + "graph": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant", + "guid": "94f3eede-9aa3-4088-92a3-bb9a56509fad", + "link": "https://learn.microsoft.com/azure/firewall/dns-details", + "service": "Firewall", "severity": "Média", - "text": "Monitore a disponibilidade e a utilização do ExpressRoute usando o Express Route Insights interno.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Operações" + "text": "Habilite a configuração de proxy DNS do Firewall do Azure.", + "training": "https://learn.microsoft.com/training/courses/az-700t00/", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", - "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", - "service": "ExpressRoute", - "severity": "Média", - "text": "Use o Monitor da Conexão para monitoramento de conectividade em toda a rede, especialmente entre o local e o Azure.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "guid": "1dc04554-dece-4ffb-a49e-5c683e09f8da", + "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", + "service": "Firewall", + "severity": "Alto", + "text": "Integre o Firewall do Azure ao Azure Monitor e habilite o log de diagnóstico para armazenar e analisar logs e métricas de firewall.", + "training": "https://learn.microsoft.com/training/courses/az-700t00/", "waf": "Operações" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)", - "guid": "e0d5973c-d4cd-421b-8881-37f5e6c4cfd3", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution", - "service": "ExpressRoute", - "severity": "Média", - "text": "Use circuitos do ExpressRoute de diferentes locais de emparelhamento para redundância.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "guid": "64e7000e-3c06-485e-b455-ced7f454cba3", + "link": "https://learn.microsoft.com/azure/well-architected/service-guides/azure-firewall", + "service": "Firewall", + "severity": "Baixo", + "text": "Implementar backups para suas regras de firewall", + "training": "https://learn.microsoft.com/training/courses/az-104t00/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "cf3fe65c-fec0-495a-8edc-9675200f2add", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager", - "service": "ExpressRoute", - "severity": "Média", - "text": "Use a VPN site a site como failover do ExpressRoute, se estiver usando apenas um único circuito do ExpressRoute.", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "graph": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'", + "guid": "d38ad60c-bc9e-4d49-b699-97e5d4dcf707", + "link": "https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell", + "service": "Firewall", + "severity": "Alto", + "text": "Implante o Firewall do Azure em várias zonas de disponibilidade. O Firewall do Azure oferece SLAs diferentes, dependendo de sua implantação; em uma única zona de disponibilidade ou em várias, melhorando potencialmente a confiabilidade e o desempenho.", + "training": "https://learn.microsoft.com/training/courses/az-104t00/", "waf": "Fiabilidade" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/azureFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))", - "guid": "72105cc8-aaea-4ee1-8c7a-ad25977afcaf", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub", - "service": "ExpressRoute", + "graph": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'", + "guid": "e8143efa-0301-4d62-be54-ca7b5ce566dc", + "link": "https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview", + "service": "Firewall", "severity": "Alto", - "text": "Se você estiver usando uma tabela de rotas no GatewaySubnet, certifique-se de que as rotas de gateway sejam propagadas.", + "text": "Configure a Proteção contra DDoS na VNet do Firewall do Azure, associe um plano de proteção contra DDoS à rede virtual que hospeda o Firewall do Azure para fornecer mitigação aprimorada contra ataques de DDoS. O Gerenciador de Firewall do Azure integra a criação de infraestrutura de firewall e planos de proteção contra DDoS. ", "waf": "Fiabilidade" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "microsoft.network/applicationGateways", "checklist": "Azure Landing Zone Review", - "guid": "d581a947-69a2-4783-942e-9df3664324c8", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", - "service": "ExpressRoute", + "guid": "d301d6e8-72e5-42e3-911c-c58b5a4b1511", + "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", + "service": "App Gateway", "severity": "Alto", - "text": "Se estiver usando o ExpressRoute, o roteamento local deverá ser dinâmico: no caso de uma falha de conexão, ele deverá convergir para a conexão restante do circuito. A carga deve ser compartilhada entre ambas as conexões, idealmente como ativa/ativa, embora ativa/passiva também seja suportada.", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "text": "Não interrompa a comunicação do painel de controle para serviços de PaaS do Azure injetados em redes virtuais, como com uma rota 0.0.0.0/0 ou uma regra NSG que bloqueia o tráfego do painel de controle.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "b258f058-b9f6-46cd-b28d-990106f0c3f8", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute", + "guid": "b3e4563a-4d87-4397-98b6-62d6d15f512a", + "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview", "service": "ExpressRoute", "severity": "Média", - "text": "Verifique se os dois links físicos do circuito do ExpressRoute estão conectados a dois dispositivos de borda distintos em sua rede.", + "text": "Acesse os serviços de PaaS do Azure localmente por meio de pontos de extremidade privados e emparelhamento privado do ExpressRoute. Esse método evita o trânsito pela Internet pública.", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "fe2a1b53-6fbd-4c67-b58a-85d7c7a0afcb", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-bfd", - "service": "ExpressRoute", + "graph": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc", + "guid": "4704489a-8042-4d88-b79d-17b73b22a5a6", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview", + "service": "VNet", + "severity": "Alto", + "text": "Não habilite pontos de extremidade de serviço de rede virtual por padrão em todas as sub-redes.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.Network/azureFirewalls", + "checklist": "Azure Landing Zone Review", + "guid": "7e7a8ed4-b30e-438c-9f29-812b2363cefe", + "link": "azure/private-link/inspect-traffic-with-azure-firewall", + "service": "Firewall", "severity": "Média", - "text": "Certifique-se de que a Detecção de Encaminhamento Bidirecional (BFD) esteja habilitada e configurada em dispositivos de roteamento de borda do cliente ou provedor.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "text": "Filtre o tráfego de saída para os serviços de PaaS do Azure usando FQDNs em vez de endereços IP no Firewall do Azure ou em uma NVA para evitar a exfiltração de dados. Se estiver usando o Link Privado, você poderá bloquear todos os FQDNs, caso contrário, permita apenas os serviços de PaaS necessários.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "Segurança" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "669b215a-ce43-4371-8f6f-11047f6490f1", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", + "guid": "f2aad7e3-bb03-4adc-8606-4123d342a917", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", "service": "ExpressRoute", "severity": "Alto", - "text": "Conecte o Gateway do ExpressRoute a dois ou mais circuitos de diferentes locais de emparelhamento para maior resiliência.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Fiabilidade" + "text": "Utilize pelo menos um prefixo /27 para as sub-redes do Gateway.", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/networkSecurityGroups", "checklist": "Azure Landing Zone Review", - "guid": "3f79ed00-203b-4c95-9efd-691505f5a1f9", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-howto-setup-alerts-virtual-network-gateway-log", - "service": "ExpressRoute", - "severity": "Média", - "text": "Configure logs de diagnóstico e alertas para o gateway de rede virtual do ExpressRoute.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Operações" + "graph": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)", + "guid": "11deb39d-8299-4e47-bbe0-0fb5a36318a8", + "link": "https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags", + "service": "NSG", + "severity": "Alto", + "text": "Não confie nas regras padrão de entrada do NSG usando a marca de serviço VirtualNetwork para limitar a conectividade.", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/networkSecurityGroups", "checklist": "Azure Landing Zone Review", - "guid": "5234c93f-b651-41dd-80c1-234177b91ced", - "link": "https://learn.microsoft.com/azure/expressroute/virtual-network-connectivity-guidance", - "service": "ExpressRoute", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant", + "guid": "872e52e3-611c-4c58-a5a4-b1511e43a58a", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", + "service": "NSG", "severity": "Média", - "text": "Não use circuitos do ExpressRoute para comunicação VNet para VNet.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "Desempenho" + "text": "Use NSGs para ajudar a proteger o tráfego entre sub-redes, bem como o tráfego leste/oeste na plataforma (tráfego entre zonas de destino).", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" }, { + "arm-service": "Microsoft.Network/networkSecurityGroups", "checklist": "Azure Landing Zone Review", - "guid": "8ac6a9e0-1e6a-483d-b5de-32c199248160", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-about", - "service": "N/A", - "severity": "Baixo", - "text": "Não envie o tráfego do Azure para locais híbridos para inspeção. Em vez disso, siga o princípio \"o tráfego no Azure permanece no Azure\" para que a comunicação entre os recursos no Azure ocorra por meio da rede de backbone da Microsoft.", - "waf": "Desempenho" + "guid": "a4d87397-48b6-462d-9d15-f512a65498f6", + "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "service": "NSG", + "severity": "Média", + "text": "Use NSGs e grupos de segurança de aplicativos para microssegmentar o tráfego dentro da zona de destino e evite usar uma NVA central para filtrar fluxos de tráfego.", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Network/networkSecurityGroups", "checklist": "Azure Landing Zone Review", - "guid": "e6c4cfd3-e504-4547-a244-7ec66138a720", - "link": "https://learn.microsoft.com/azure/firewall/overview", - "service": "Firewall", - "severity": "Alto", - "text": "Use o Firewall do Azure para controlar o tráfego de saída do Azure para a Internet, conexões de entrada não HTTP/S e filtragem de tráfego Leste/Oeste (se a organização exigir).", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "graph": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant", + "guid": "dfe237de-143b-416c-91d7-aa9b64704489", + "link": "https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview", + "service": "NSG", + "severity": "Média", + "text": "Habilite os Logs de Fluxo de VNet e alimente-os na Análise de Tráfego para obter insights sobre fluxos de tráfego internos e externos.", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Network/networkSecurityGroups", "checklist": "Azure Landing Zone Review", - "guid": "5a4b1511-e43a-458a-ac22-99c4d7b57d0c", - "link": "https://learn.microsoft.com/azure/firewall-manager/policy-overview", - "service": "Firewall", + "graph": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)", + "guid": "0390417d-53dc-44d9-b3f4-c8832f359b41", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", + "service": "NSG", "severity": "Média", - "text": "Crie uma política global de Firewall do Azure para controlar a postura de segurança em todo o ambiente de rede global e atribua-a a todas as instâncias do Firewall do Azure. Permita que políticas granulares atendam aos requisitos de regiões específicas delegando políticas de firewall incrementais às equipes de segurança locais por meio do controle de acesso baseado em função do Azure.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Segurança" + "text": "Não implemente mais de 900 regras de NSG por NSG, devido ao limite de 1000 regras.", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "guid": "655562f2-b3e4-4563-a4d8-739748b662d6", - "link": "https://learn.microsoft.com/azure/firewall-manager/deploy-trusted-security-partner", - "service": "Firewall", - "severity": "Baixo", - "text": "Configure provedores de segurança SaaS de parceiros compatíveis no Firewall Manager se a organização quiser usar essas soluções para ajudar a proteger as conexões de saída.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Segurança" + "guid": "412e7f98-3f63-4047-82dd-69c5b5c2622f", + "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-any-to-any", + "service": "VWAN", + "severity": "Média", + "text": "Use a WAN Virtual se o cenário estiver explicitamente descrito na lista de designs de roteamento da WAN Virtual.", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant", - "guid": "14d99880-2f88-47e8-a134-62a7d85c94af", - "link": "https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules", - "service": "Firewall", - "severity": "Alto", - "text": "Use regras de aplicativo para filtrar o tráfego de saída no nome do host de destino para protocolos com suporte. Use regras de rede baseadas em FQDN e Firewall do Azure com proxy DNS para filtrar o tráfego de saída para a Internet em outros protocolos.", + "guid": "54b69bad-33aa-4d5e-ac68-e1d76667313b", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/virtual-wan-network-topology#virtual-wan-network-design-recommendationst", + "service": "VWAN", + "severity": "Média", + "text": "Use um hub de WAN Virtual por região do Azure para conectar várias zonas de destino entre regiões do Azure por meio de uma WAN Virtual do Azure global comum.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Desempenho" + }, + { + "arm-service": "microsoft.network/virtualWans", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant", + "guid": "7d5d1e4e-6146-458d-9558-fd77249b8211", + "link": "https://learn.microsoft.com/azure/virtual-wan/howto-firewall", + "service": "VWAN", + "severity": "Média", + "text": "Para proteção e filtragem de tráfego de saída da Internet, implante o Firewall do Azure em hubs seguros.", "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant", - "guid": "c10d51ef-f999-455d-bba0-5c90ece07447", - "link": "https://learn.microsoft.com/azure/firewall/premium-features", - "service": "Firewall", - "severity": "Alto", - "text": "Use o Firewall do Azure Premium para habilitar recursos de segurança adicionais.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-firewall/", - "waf": "Segurança" + "guid": "6667313b-4f56-464b-9e98-4a859c773e7d", + "link": "https://learn.microsoft.com/azure/virtual-wan/migrate-from-hub-spoke-topology", + "service": "VWAN", + "severity": "Média", + "text": "Verifique se a arquitetura de rede da WAN virtual está alinhada a um cenário de arquitetura identificado.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant", - "guid": "e9c8f584-6d5e-473b-8dc5-acc9fbaab4e3", - "link": "https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules", - "service": "Firewall", - "severity": "Alto", - "text": "Configure o modo de Inteligência contra Ameaças do Firewall do Azure como Alerta e Negação para proteção adicional.", - "waf": "Segurança" + "guid": "261623a7-65a9-417e-8f34-8ef254c27d42", + "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", + "service": "VWAN", + "severity": "Média", + "text": "Use o Azure Monitor Insights para WAN Virtual para monitorar a topologia de ponta a ponta da WAN Virtual, o status e as principais métricas.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant", - "guid": "b9d0dff5-bdd4-4cd8-88ed-5811610b2b2c", - "link": "https://learn.microsoft.com/azure/firewall/premium-features#idps", - "service": "Firewall", - "severity": "Alto", - "text": "Configure o modo IDPS do Firewall do Azure como Negar para proteção adicional.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-firewall/", - "waf": "Segurança" + "graph": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant", + "guid": "727c77e1-b9aa-4a37-a024-129d042422c1", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan", + "service": "VWAN", + "severity": "Média", + "text": "Não desabilite o tráfego branch a branch na WAN Virtual, a menos que esses fluxos devam ser bloqueados explicitamente.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant", - "guid": "a3784907-9836-4271-aafc-93535f8ec08b", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview", - "service": "Firewall", - "severity": "Alto", - "text": "Para sub-redes em VNets não conectadas à WAN Virtual, anexe uma tabela de rotas para que o tráfego da Internet seja redirecionado para o Firewall do Azure ou uma Solução de Virtualização de Rede.", - "waf": "Segurança" + "graph": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant", + "guid": "d49ac006-6670-4bc9-9948-d3e0a3a94f4d", + "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", + "service": "VWAN", + "severity": "Média", + "text": "Use AS-Path como preferência de roteamento de hub, pois é mais flexível que ExpressRoute ou VPN.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "guid": "715d833d-4708-4527-90ac-1b142c7045ba", - "link": "https://learn.microsoft.com/azure/firewall/firewall-structured-logs", - "service": "Firewall", + "guid": "2586b854-237e-47f1-84a1-d45d4cd2310d", + "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", + "service": "VWAN", "severity": "Média", - "text": "Adicione configurações de diagnóstico para salvar logs, usando a tabela de destino Específico do Recurso, para todas as implantações do Firewall do Azure.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Operações" + "text": "Configure a propagação baseada em rótulos na WAN Virtual, caso contrário, a conectividade entre hubs virtuais será prejudicada.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "microsoft.network/virtualWans", "checklist": "Azure Landing Zone Review", - "guid": "e960fc6b-4ab2-4db6-9609-3745135f9ffa", - "link": "https://learn.microsoft.com/azure/firewall-manager/migrate-to-policy", - "service": "Firewall", + "graph": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant", + "guid": "9c75dfef-573c-461c-a698-68598595581a", + "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation", + "service": "VWAN", "severity": "Alto", - "text": "Migre das regras clássicas do Firewall do Azure (se houver) para a Política de Firewall.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Operações" + "text": "Atribua pelo menos um prefixo /23 a hubs virtuais para garantir que haja espaço IP suficiente disponível.", + "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant", - "guid": "22d6419e-b627-4d95-9e7d-019fa759387f", - "link": "https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size", - "service": "Firewall", + "guid": "5c986cb2-9131-456a-8247-6e49f541acdc", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Policy", "severity": "Alto", - "text": "Use um prefixo /26 para suas sub-redes do Firewall do Azure.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-firewall/", + "text": "Aproveite o Azure Policy estrategicamente, defina controles para seu ambiente, usando Iniciativas de Política para agrupar políticas relacionadas.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "828cec2e-af6c-40c2-8fa2-1b681ee63eb7", - "link": "https://learn.microsoft.com/azure/firewall-manager/rule-hierarchy", - "service": "Firewall", + "guid": "d8a2adb1-17d6-4326-af62-5ca44e5695f2", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Policy", "severity": "Média", - "text": "Organize as regras dentro da política de firewall em Grupos de Coleção de Regras e Coleções de Regras e com base em sua frequência de uso.", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-firewall-manager/", - "waf": "Desempenho" + "text": "Mapeie os requisitos regulatórios e de conformidade para definições do Azure Policy e atribuições de função do Azure.", + "training": "https://learn.microsoft.com/training/modules/governance-security/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "0da83bb1-2f39-49af-b5c9-835fc455e3d1", - "link": "https://learn.microsoft.com/azure/firewall/ip-groups", - "service": "Firewall", + "guid": "223ace8c-b123-408c-a501-7f154e3ab369", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Policy", "severity": "Média", - "text": "Use grupos de IP ou prefixos de IP para reduzir o número de regras de tabela de IP.", - "waf": "Desempenho" - }, - { - "arm-service": "Microsoft.Network/azureFirewalls", - "checklist": "Azure Landing Zone Review", - "guid": "c44c6f0e-1642-4a61-a17b-0922f835c93a", - "link": "https://learn.microsoft.com/azure/firewall/tutorial-firewall-dnat", - "service": "Firewall", - "severity": "Média", - "text": "Não use curingas como um IP de origem para DNATS, como * ou any, você deve especificar IPs de origem para DNATs de entrada.", - "training": "https://learn.microsoft.com/training/modules/introduction-to-azure-virtual-networks/", - "waf": "Desempenho" - }, - { - "arm-service": "Microsoft.Network/azureFirewalls", - "checklist": "Azure Landing Zone Review", - "guid": "7371dc21-251a-47a3-af14-6e01b9da4757", - "link": "https://learn.microsoft.com/azure/firewall/integrate-with-nat-gateway", - "service": "Firewall", - "severity": "Média", - "text": "Evite o esgotamento da porta SNAT monitorando o uso da porta SNAT, avaliando as configurações do NAT Gateway e garantindo um failover contínuo. Se a contagem de portas se aproximar do limite, é um sinal de que o esgotamento do SNAT pode ser iminente.", - "training": "https://learn.microsoft.com/training/modules/introduction-to-azure-virtual-networks/", - "waf": "Desempenho" + "text": "Estabeleça definições do Azure Policy no grupo de gerenciamento raiz intermediário para que elas possam ser atribuídas em escopos herdados.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "346840b8-1064-496e-8396-4b1340172d52", - "link": "https://learn.microsoft.com/azure/firewall/premium-features#tls-inspection", - "service": "Firewall", + "guid": "3829e7e3-1618-4368-9a04-77a209945bda", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Policy", "severity": "Alto", - "text": "Se você estiver usando o Firewall do Azure Premium, habilite a Inspeção TLS.", - "waf": "Desempenho" + "text": "Gerencie atribuições de política no nível apropriado mais alto com exclusões nos níveis inferiores, se necessário.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "39990a13-915c-45f9-a2d3-562d7d6c4b7c", - "link": "https://learn.microsoft.com/azure/firewall/premium-features#web-categories", - "service": "Firewall", + "guid": "43334f24-9116-4341-a2ba-527526944008", + "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", + "service": "Policy", "severity": "Baixo", - "text": "Use categorias da Web para permitir ou negar o acesso de saída a tópicos específicos.", - "waf": "Desempenho" + "text": "Use o Azure Policy para controlar quais serviços os usuários podem provisionar no nível da assinatura/grupo de gerenciamento.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "6eff7e6c-6c4a-43d7-be3f-6641c2cb3d4a", - "link": "https://learn.microsoft.com/azure/architecture/example-scenario/gateway/application-gateway-before-azure-firewall", - "service": "Firewall", - "severity": "Média", - "text": "Como parte da inspeção TLS, planeje o recebimento de tráfego dos Gateways de Aplicativo do Azure para inspeção.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-application-gateway/", - "waf": "Desempenho" + "guid": "be7d7e48-4327-46d8-adc0-55bcf619e8a1", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Policy", + "severity": "Alto", + "text": "Use políticas internas sempre que possível para minimizar a sobrecarga operacional.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant", - "guid": "94f3eede-9aa3-4088-92a3-bb9a56509fad", - "link": "https://learn.microsoft.com/azure/firewall/dns-details", - "service": "Firewall", + "description": "Atribuir a função Colaborador de Política de Recursos a escopos específicos permite delegar o gerenciamento de políticas a equipes relevantes. Por exemplo, uma equipe central de TI pode supervisionar as políticas no nível do grupo de gerenciamento, enquanto as equipes de aplicativos lidam com as políticas de suas assinaturas, permitindo a governança distribuída com adesão aos padrões organizacionais.", + "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", + "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", + "service": "Policy", "severity": "Média", - "text": "Habilite a configuração de proxy DNS do Firewall do Azure.", - "training": "https://learn.microsoft.com/training/courses/az-700t00/", + "text": "Atribua a função interna de Colaborador de Política de Recursos em um escopo específico para habilitar a governança no nível do aplicativo.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", - "checklist": "Azure Landing Zone Review", - "guid": "1dc04554-dece-4ffb-a49e-5c683e09f8da", - "link": "https://learn.microsoft.com/azure/firewall/firewall-diagnostics", - "service": "Firewall", - "severity": "Alto", - "text": "Integre o Firewall do Azure ao Azure Monitor e habilite o log de diagnóstico para armazenar e analisar logs e métricas de firewall.", - "training": "https://learn.microsoft.com/training/courses/az-700t00/", - "waf": "Operações" - }, - { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "64e7000e-3c06-485e-b455-ced7f454cba3", - "link": "https://learn.microsoft.com/azure/well-architected/service-guides/azure-firewall", - "service": "Firewall", - "severity": "Baixo", - "text": "Implementar backups para suas regras de firewall", - "training": "https://learn.microsoft.com/training/courses/az-104t00/", - "waf": "Operações" + "guid": "19048384-5c98-46cb-8913-156a12476e49", + "link": "https://learn.microsoft.com/azure/governance/policy/overview", + "service": "Policy", + "severity": "Média", + "text": "Limite o número de atribuições do Azure Policy feitas no escopo do grupo de gerenciamento raiz para evitar o gerenciamento por meio de exclusões em escopos herdados.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'", - "guid": "d38ad60c-bc9e-4d49-b699-97e5d4dcf707", - "link": "https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell", - "service": "Firewall", - "severity": "Alto", - "text": "Implante o Firewall do Azure em várias zonas de disponibilidade. O Firewall do Azure oferece SLAs diferentes, dependendo de sua implantação; em uma única zona de disponibilidade ou em várias, melhorando potencialmente a confiabilidade e o desempenho.", - "training": "https://learn.microsoft.com/training/courses/az-104t00/", - "waf": "Fiabilidade" + "guid": "5a917e1f-348e-4f25-9c27-d42e8bbac757", + "link": "https://learn.microsoft.com/industry/release-plan/2023wave2/cloud-sovereignty/enable-data-sovereignty-policy-baseline", + "service": "Policy", + "severity": "Média", + "text": "Se houver requisitos de soberania de dados, as Políticas do Azure deverão ser implantadas para aplicá-los.", + "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'", - "guid": "e8143efa-0301-4d62-be54-ca7b5ce566dc", - "link": "https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview", - "service": "Firewall", - "severity": "Alto", - "text": "Configure a Proteção contra DDoS na VNet do Firewall do Azure, associe um plano de proteção contra DDoS à rede virtual que hospeda o Firewall do Azure para fornecer mitigação aprimorada contra ataques de DDoS. O Gerenciador de Firewall do Azure integra a criação de infraestrutura de firewall e planos de proteção contra DDoS. ", - "waf": "Fiabilidade" + "guid": "78b22132-b41c-460b-a4d3-df8f73a67dc2", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/sovereign-landing-zone", + "service": "Policy", + "severity": "Média", + "text": "Para a Zona de Destino Soberana, implante a linha de base da política de soberania e atribua no nível correto do grupo de gerenciamento.", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/applicationGateways", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "d301d6e8-72e5-42e3-911c-c58b5a4b1511", - "link": "https://learn.microsoft.com/azure/virtual-network/vnet-integration-for-azure-services", - "service": "App Gateway", - "severity": "Alto", - "text": "Não interrompa a comunicação do painel de controle para serviços de PaaS do Azure injetados em redes virtuais, como com uma rota 0.0.0.0/0 ou uma regra NSG que bloqueia o tráfego do painel de controle.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "guid": "caeea0e9-1024-41df-a52e-d99c3f22a6f4", + "link": "https://learn.microsoft.com/industry/sovereignty/policy-portfolio-baseline", + "service": "Policy", + "severity": "Média", + "text": "Para Zona de Aterrissagem Soberana, documente os objetivos de Controle Soberano para mapeamento de políticas.", "waf": "Segurança" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Authorization/policyDefinitions", "checklist": "Azure Landing Zone Review", - "guid": "b3e4563a-4d87-4397-98b6-62d6d15f512a", - "link": "https://learn.microsoft.com/azure/private-link/private-endpoint-overview", - "service": "ExpressRoute", + "guid": "9b461617-db7b-4399-8ac6-d4eb7153893a", + "link": "https://learn.microsoft.com/industry/sovereignty/policy-portfolio-baseline#sovereignty-baseline-policy-initiatives", + "service": "Policy", "severity": "Média", - "text": "Acesse os serviços de PaaS do Azure localmente por meio de pontos de extremidade privados e emparelhamento privado do ExpressRoute. Esse método evita o trânsito pela Internet pública.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "text": "Para a Zona de Aterrissagem Soberana, certifique-se de que o processo esteja em vigor para o gerenciamento de 'Objetivos de Controle Soberano para mapeamento de políticas'.", "waf": "Segurança" }, { - "arm-service": "Microsoft.Network/virtualNetworks", + "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc", - "guid": "4704489a-8042-4d88-b79d-17b73b22a5a6", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview", - "service": "VNet", - "severity": "Alto", - "text": "Não habilite pontos de extremidade de serviço de rede virtual por padrão em todas as sub-redes.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", - "waf": "Segurança" + "guid": "67e7a8ed-4b30-4e38-a3f2-9812b2363cef", + "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/logs/workspace-design#azure-regions", + "service": "Monitor", + "severity": "Média", + "text": "Use um workspace de logs de monitor único para gerenciar plataformas centralmente, exceto quando o RBAC (controle de acesso baseado em função) do Azure, os requisitos de soberania de dados ou as políticas de retenção de dados exigirem workspaces separados.", + "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/azureFirewalls", + "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "7e7a8ed4-b30e-438c-9f29-812b2363cefe", - "link": "azure/private-link/inspect-traffic-with-azure-firewall", - "service": "Firewall", + "guid": "7418ada9-4199-4c28-8286-d15e9433e8f3", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "service": "Monitor", "severity": "Média", - "text": "Filtre o tráfego de saída para os serviços de PaaS do Azure usando FQDNs em vez de endereços IP no Firewall do Azure ou em uma NVA para evitar a exfiltração de dados. Se estiver usando o Link Privado, você poderá bloquear todos os FQDNs, caso contrário, permita apenas os serviços de PaaS necessários.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", - "waf": "Segurança" + "text": "Decida se deseja usar um único workspace de Logs do Azure Monitor para todas as regiões ou criar vários workspaces para abranger várias regiões geográficas. Cada abordagem tem vantagens e desvantagens, incluindo possíveis cobranças de rede entre regiões", + "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", + "waf": "Fiabilidade" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", - "guid": "f2aad7e3-bb03-4adc-8606-4123d342a917", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway", - "service": "ExpressRoute", + "guid": "5e6c4cfd-3e50-4454-9c24-47ec66138a72", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", + "service": "Monitor", "severity": "Alto", - "text": "Utilize pelo menos um prefixo /27 para as sub-redes do Gateway.", - "waf": "Segurança" + "text": "Exporte logs para o Armazenamento do Azure se os requisitos de retenção de log excederem doze anos. Use o armazenamento imutável com uma política de gravação única e leitura múltipla para tornar os dados não apagáveis e não modificáveis por um intervalo especificado pelo usuário.", + "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/networkSecurityGroups", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)", - "guid": "11deb39d-8299-4e47-bbe0-0fb5a36318a8", - "link": "https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags", - "service": "NSG", - "severity": "Alto", - "text": "Não confie nas regras padrão de entrada do NSG usando a marca de serviço VirtualNetwork para limitar a conectividade.", - "waf": "Segurança" + "guid": "e7d7e484-3276-4d8b-bc05-5bcf619e8a13", + "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", + "service": "VM", + "severity": "Média", + "text": "Monitore o descompasso de configuração da VM (máquina virtual) no nível do sistema operacional usando o Azure Policy. Habilitar os recursos de auditoria da Configuração de Computador do Gerenciamento Automatizado do Azure por meio da política ajuda as cargas de trabalho da equipe de aplicativos a consumir imediatamente os recursos de recursos com pouco esforço.", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/networkSecurityGroups", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant", - "guid": "872e52e3-611c-4c58-a5a4-b1511e43a58a", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation", - "service": "NSG", + "guid": "f9887952-5d62-4688-9d70-ba6c97be9951", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#update-management-considerations", + "service": "VM", "severity": "Média", - "text": "Use NSGs para ajudar a proteger o tráfego entre sub-redes, bem como o tráfego leste/oeste na plataforma (tráfego entre zonas de destino).", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "waf": "Segurança" + "text": "Use o Azure Update Manager como um mecanismo de aplicação de patch para VMs Windows e Linux no Azure.", + "training": "https://learn.microsoft.com/azure/update-manager/overview?tabs=azure-vms", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/networkSecurityGroups", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "a4d87397-48b6-462d-9d15-f512a65498f6", - "link": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", - "service": "NSG", + "guid": "c806c048-26b7-4ddf-b4c2-b4f0c476925d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#update-management-considerations ", + "service": "VM", "severity": "Média", - "text": "Use NSGs e grupos de segurança de aplicativos para microssegmentar o tráfego dentro da zona de destino e evite usar uma NVA central para filtrar fluxos de tráfego.", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", - "waf": "Segurança" + "text": "Use o Gerenciador de Atualizações do Azure como um mecanismo de aplicação de patch para VMs do Windows e do Linux fora do Azure usando o Azure Arc.", + "training": "https://learn.microsoft.com/azure/update-manager/overview?tabs=azure-vms", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/networkSecurityGroups", + "arm-service": "microsoft.network/networkWatchers", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant", - "guid": "dfe237de-143b-416c-91d7-aa9b64704489", - "link": "https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview", - "service": "NSG", + "guid": "90483845-c986-4cb2-a131-56a12476e49f", + "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", + "service": "Network Watcher", "severity": "Média", - "text": "Habilite os Logs de Fluxo de VNet e alimente-os na Análise de Tráfego para obter insights sobre fluxos de tráfego internos e externos.", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", - "waf": "Segurança" + "text": "Use o Observador de Rede para monitorar proativamente os fluxos de tráfego.", + "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Network/networkSecurityGroups", + "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)", - "guid": "0390417d-53dc-44d9-b3f4-c8832f359b41", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits", - "service": "NSG", + "guid": "6944008b-e7d7-4e48-9327-6d8bdc055bcf", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", + "service": "Monitor", "severity": "Média", - "text": "Não implemente mais de 900 regras de NSG por NSG, devido ao limite de 1000 regras.", - "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", - "waf": "Fiabilidade" + "text": "Use os Logs do Azure Monitor para obter insights e relatórios.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-monitor/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "412e7f98-3f63-4047-82dd-69c5b5c2622f", - "link": "https://learn.microsoft.com/azure/virtual-wan/scenario-any-to-any", - "service": "VWAN", + "guid": "97be9951-9048-4384-9c98-6cb2913156a1", + "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", + "service": "Monitor", "severity": "Média", - "text": "Use a WAN Virtual se o cenário estiver explicitamente descrito na lista de designs de roteamento da WAN Virtual.", - "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "text": "Use alertas do Azure Monitor para a geração de alertas operacionais.", + "training": "https://learn.microsoft.com/training/modules/incident-response-with-alerting-on-azure/", "waf": "Operações" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "54b69bad-33aa-4d5e-ac68-e1d76667313b", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/virtual-wan-network-topology#virtual-wan-network-design-recommendationst", - "service": "VWAN", + "guid": "fed3c55f-a67e-4875-aadd-3aba3f9fde31", + "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", + "service": "Monitor", "severity": "Média", - "text": "Use um hub de WAN Virtual por região do Azure para conectar várias zonas de destino entre regiões do Azure por meio de uma WAN Virtual do Azure global comum.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Desempenho" + "text": "Ao usar o Acompanhamento de Alterações e Inventário por meio de Contas de Automação do Azure, verifique se você selecionou regiões com suporte para vincular seu workspace do Log Analytics e contas de automação.", + "training": "https://learn.microsoft.com/training/modules/explore-azure-automation-devops/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.RecoveryServices/vaults", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant", - "guid": "7d5d1e4e-6146-458d-9558-fd77249b8211", - "link": "https://learn.microsoft.com/azure/virtual-wan/howto-firewall", - "service": "VWAN", - "severity": "Média", - "text": "Para proteção e filtragem de tráfego de saída da Internet, implante o Firewall do Azure em hubs seguros.", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "Segurança" + "guid": "eba8cf22-45c6-4dc1-9b57-2cceb3b97ce5", + "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", + "service": "Backup", + "severity": "Baixo", + "text": "Ao usar o Backup do Azure, use os tipos de backup corretos (GRS, ZRS E LRS) para o backup, pois a configuração padrão é GRS.", + "training": "https://learn.microsoft.com/training/modules/design-solution-for-backup-disaster-recovery/", + "waf": "Fiabilidade" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "6667313b-4f56-464b-9e98-4a859c773e7d", - "link": "https://learn.microsoft.com/azure/virtual-wan/migrate-from-hub-spoke-topology", - "service": "VWAN", + "guid": "f541acdc-e979-4377-acdb-3751ab2ab13a", + "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", + "service": "VM", "severity": "Média", - "text": "Verifique se a arquitetura de rede da WAN virtual está alinhada a um cenário de arquitetura identificado.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Fiabilidade" + "text": "Use as políticas de convidado do Azure para implantar automaticamente as configurações de software por meio de extensões de VM e impor uma configuração de VM de linha de base compatível.", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "261623a7-65a9-417e-8f34-8ef254c27d42", - "link": "https://learn.microsoft.com/azure/virtual-wan/azure-monitor-insights", - "service": "VWAN", + "description": "Use os recursos de configuração de convidado do Azure Policy para auditar e corrigir as configurações do computador (por exemplo, sistema operacional, aplicativo, ambiente) para garantir que os recursos estejam alinhados com as configurações esperadas e que o Gerenciamento de Atualizações possa impor o gerenciamento de patches para VMs.", + "guid": "da6e55d7-d8a2-4adb-817d-6326af625ca4", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", + "service": "VM", "severity": "Média", - "text": "Use o Azure Monitor Insights para WAN Virtual para monitorar a topologia de ponta a ponta da WAN Virtual, o status e as principais métricas.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Operações" + "text": "Monitore o descompasso de configuração de segurança da VM por meio do Azure Policy.", + "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "graph": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant", - "guid": "727c77e1-b9aa-4a37-a024-129d042422c1", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan", - "service": "VWAN", + "guid": "2476e49f-541a-4cdc-b979-377bcdb3751a", + "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", + "service": "VM", "severity": "Média", - "text": "Não desabilite o tráfego branch a branch na WAN Virtual, a menos que esses fluxos devam ser bloqueados explicitamente.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Fiabilidade" + "text": "Use o Azure Site Recovery para cenários de recuperação de desastre de Máquinas Virtuais do Azure para o Azure. Isso permite replicar cargas de trabalho entre regiões.", + "training": "https://learn.microsoft.com/training/modules/protect-infrastructure-with-site-recovery/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "Microsoft.RecoveryServices/vaults", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant", - "guid": "d49ac006-6670-4bc9-9948-d3e0a3a94f4d", - "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference", - "service": "VWAN", + "guid": "f625ca44-e569-45f2-823a-ce8cb12308ca", + "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", + "service": "Backup", "severity": "Média", - "text": "Use AS-Path como preferência de roteamento de hub, pois é mais flexível que ExpressRoute ou VPN.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Fiabilidade" + "text": "Use recursos de backup nativos do Azure ou uma solução de backup de terceiros compatível com o Azure.", + "training": "https://learn.microsoft.com/training/modules/design-solution-for-backup-disaster-recovery/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "2586b854-237e-47f1-84a1-d45d4cd2310d", - "link": "https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing#labels", - "service": "VWAN", - "severity": "Média", - "text": "Configure a propagação baseada em rótulos na WAN Virtual, caso contrário, a conectividade entre hubs virtuais será prejudicada.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Fiabilidade" + "guid": "89cc5e11-aa4d-4c3b-893d-feb99215266a", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", + "service": "WAF", + "severity": "Alto", + "text": "Adicione configurações de diagnóstico para salvar logs do WAF de serviços de entrega de aplicativos, como o Azure Front Door e o Gateway de Aplicativo do Azure. Revise regularmente os logs para verificar se há ataques e detecções de falsos positivos.", + "training": "https://learn.microsoft.com/training/modules/capture-application-logs-app-service/", + "waf": "Operações" }, { - "arm-service": "microsoft.network/virtualWans", + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant", - "guid": "9c75dfef-573c-461c-a698-68598595581a", - "link": "https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation", - "service": "VWAN", - "severity": "Alto", - "text": "Atribua pelo menos um prefixo /23 a hubs virtuais para garantir que haja espaço IP suficiente disponível.", - "training": "https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/", - "waf": "Fiabilidade" + "guid": "7f408960-c626-44cb-a018-347c8d790cdf", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", + "service": "WAF", + "severity": "Média", + "text": "Envie logs do WAF de seus serviços de entrega de aplicativos, como o Azure Front Door e o Gateway de Aplicativo do Azure, para o Microsoft Sentinel. Detecte ataques e integre a telemetria do WAF ao seu ambiente geral do Azure.", + "training": "https://learn.microsoft.com/training/paths/sc-200-connect-logs-to-azure-sentinel/", + "waf": "Operações" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "5c986cb2-9131-456a-8247-6e49f541acdc", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Policy", + "guid": "5017f154-e3ab-4369-9829-e7e316183687", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview", + "service": "Key Vault", "severity": "Alto", - "text": "Aproveite o Azure Policy estrategicamente, defina controles para seu ambiente, usando Iniciativas de Política para agrupar políticas relacionadas.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "text": "Use o Azure Key Vault para armazenar seus segredos e credenciais.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "d8a2adb1-17d6-4326-af62-5ca44e5695f2", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Policy", + "graph": "ResourceContainers | where type=='microsoft.resources/subscriptions'| parse id with '/subscriptions/' SubscriptionID| project subscriptionId, SubscriptionName = name| join kind=leftouter (Resources| where type == 'microsoft.keyvault/vaults'| project id, name, subscriptionId) on subscriptionId| join kind= leftouter (Resources| where type == 'microsoft.keyvault/vaults'| summarize ResourceCount = count() by subscriptionId) on subscriptionId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 1)", + "guid": "a0477a20-9945-4bda-9333-4f2491163418", + "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", + "service": "Key Vault", "severity": "Média", - "text": "Mapeie os requisitos regulatórios e de conformidade para definições do Azure Policy e atribuições de função do Azure.", - "training": "https://learn.microsoft.com/training/modules/governance-security/", + "text": "Use diferentes Azure Key Vaults para diferentes aplicativos e regiões para evitar limites de escala de transação e restringir o acesso a segredos.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "223ace8c-b123-408c-a501-7f154e3ab369", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Policy", + "guid": "2ba52752-6944-4008-ae7d-7e4843276d8b", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Média", - "text": "Estabeleça definições do Azure Policy no grupo de gerenciamento raiz intermediário para que elas possam ser atribuídas em escopos herdados.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "text": "Provisione o Azure Key Vault com as políticas de exclusão reversível e limpeza habilitadas para permitir a proteção de retenção para objetos excluídos.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "3829e7e3-1618-4368-9a04-77a209945bda", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Policy", - "severity": "Alto", - "text": "Gerencie atribuições de política no nível apropriado mais alto com exclusões nos níveis inferiores, se necessário.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "guid": "dc055bcf-619e-48a1-9f98-879525d62688", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", + "severity": "Média", + "text": "Siga um modelo de privilégios mínimos limitando a autorização para excluir permanentemente chaves, segredos e certificados a funções personalizadas especializadas de ID do Microsoft Entra.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "43334f24-9116-4341-a2ba-527526944008", - "link": "https://learn.microsoft.com/security/benchmark/azure/mcsb-asset-management#am-2-use-only-approved-services", - "service": "Policy", - "severity": "Baixo", - "text": "Use o Azure Policy para controlar quais serviços os usuários podem provisionar no nível da assinatura/grupo de gerenciamento.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "guid": "6d70ba6c-97be-4995-8904-83845c986cb2", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", + "severity": "Média", + "text": "Automatize o processo de gerenciamento e renovação de certificados com autoridades de certificação públicas para facilitar a administração.", + "training": "https://learn.microsoft.com/en-us/training/modules/configure-and-manage-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "be7d7e48-4327-46d8-adc0-55bcf619e8a1", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Policy", - "severity": "Alto", - "text": "Use políticas internas sempre que possível para minimizar a sobrecarga operacional.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "guid": "913156a1-2476-4e49-b541-acdce979377b", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", + "severity": "Média", + "text": "Estabeleça um processo automatizado para rotação de chaves e certificados.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "description": "Atribuir a função Colaborador de Política de Recursos a escopos específicos permite delegar o gerenciamento de políticas a equipes relevantes. Por exemplo, uma equipe central de TI pode supervisionar as políticas no nível do grupo de gerenciamento, enquanto as equipes de aplicativos lidam com as políticas de suas assinaturas, permitindo a governança distribuída com adesão aos padrões organizacionais.", - "guid": "3f988795-25d6-4268-a6d7-0ba6c97be995", - "link": "https://learn.microsoft.com/azure/governance/policy/overview#azure-rbac-permissions-in-azure-policy", - "service": "Policy", + "guid": "cdb3751a-b2ab-413a-ba6e-55d7d8a2adb1", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Média", - "text": "Atribua a função interna de Colaborador de Política de Recursos em um escopo específico para habilitar a governança no nível do aplicativo.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "text": "Habilite o firewall e o ponto de extremidade de serviço de rede virtual ou o ponto de extremidade privado no cofre para controlar o acesso ao cofre de chaves.", + "training": "https://learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "19048384-5c98-46cb-8913-156a12476e49", - "link": "https://learn.microsoft.com/azure/governance/policy/overview", - "service": "Policy", + "guid": "17d6326a-f625-4ca4-9e56-95f2223ace8c", + "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", + "service": "Key Vault", "severity": "Média", - "text": "Limite o número de atribuições do Azure Policy feitas no escopo do grupo de gerenciamento raiz para evitar o gerenciamento por meio de exclusões em escopos herdados.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "text": "Use o workspace do Log Analytics do Azure Monitor central da plataforma para auditar o uso de chave, certificado e segredo em cada instância do Key Vault.", + "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "5a917e1f-348e-4f25-9c27-d42e8bbac757", - "link": "https://learn.microsoft.com/industry/release-plan/2023wave2/cloud-sovereignty/enable-data-sovereignty-policy-baseline", - "service": "Policy", + "guid": "b12308ca-5017-4f15-9e3a-b3693829e7e3", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Média", - "text": "Se houver requisitos de soberania de dados, as Políticas do Azure deverão ser implantadas para aplicá-los.", - "training": "https://learn.microsoft.com/learn/paths/secure-your-cloud-data/", + "text": "Delegue a instanciação e o acesso privilegiado do Key Vault e use o Azure Policy para impor uma configuração consistente e compatível.", + "training": "https://learn.microsoft.com/training/modules/configure-azure-key-vault-networking-settings/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "78b22132-b41c-460b-a4d3-df8f73a67dc2", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/sovereign-landing-zone", - "service": "Policy", + "guid": "91163418-2ba5-4275-8694-4008be7d7e48", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Média", - "text": "Para a Zona de Destino Soberana, implante a linha de base da política de soberania e atribua no nível correto do grupo de gerenciamento.", + "text": "Use um Azure Key Vault por aplicativo por ambiente por região.", + "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "caeea0e9-1024-41df-a52e-d99c3f22a6f4", - "link": "https://learn.microsoft.com/industry/sovereignty/policy-portfolio-baseline", - "service": "Policy", + "guid": "25d62688-6d70-4ba6-a97b-e99519048384", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", "severity": "Média", - "text": "Para Zona de Aterrissagem Soberana, documente os objetivos de Controle Soberano para mapeamento de políticas.", + "text": "Se você quiser trazer suas próprias chaves, isso pode não ser compatível com todos os serviços considerados. Implemente mitigação relevante para que as inconsistências não prejudiquem os resultados desejados. Escolha pares de regiões apropriados e regiões de recuperação de desastre que minimizem a latência.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "9b461617-db7b-4399-8ac6-d4eb7153893a", - "link": "https://learn.microsoft.com/industry/sovereignty/policy-portfolio-baseline#sovereignty-baseline-policy-initiatives", - "service": "Policy", + "guid": "4ac6b67c-b3a4-4ff9-8e87-b07a7ce7bbdb", + "link": "https://learn.microsoft.com/industry/sovereignty/key-management", + "service": "Key Vault", "severity": "Média", - "text": "Para a Zona de Aterrissagem Soberana, certifique-se de que o processo esteja em vigor para o gerenciamento de 'Objetivos de Controle Soberano para mapeamento de políticas'.", + "text": "Para a Zona de Destino Soberana, use o HSM gerenciado do Azure Key Vault para armazenar seus segredos e credenciais.", + "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", "waf": "Segurança" }, { - "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "67e7a8ed-4b30-4e38-a3f2-9812b2363cef", - "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/logs/workspace-design#azure-regions", - "service": "Monitor", + "guid": "4e5695f2-223a-4ce8-ab12-308ca5017f15", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", + "service": "Entra", "severity": "Média", - "text": "Use um workspace de logs de monitor único para gerenciar plataformas centralmente, exceto quando o RBAC (controle de acesso baseado em função) do Azure, os requisitos de soberania de dados ou as políticas de retenção de dados exigirem workspaces separados.", - "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "waf": "Operações" + "text": "Use os recursos de relatório de ID do Microsoft Entra para gerar relatórios de auditoria de controle de acesso.", + "training": "https://learn.microsoft.com/training/modules/monitor-report-aad-security-events/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "7418ada9-4199-4c28-8286-d15e9433e8f3", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "service": "Monitor", - "severity": "Média", - "text": "Decida se deseja usar um único workspace de Logs do Azure Monitor para todas as regiões ou criar vários workspaces para abranger várias regiões geográficas. Cada abordagem tem vantagens e desvantagens, incluindo possíveis cobranças de rede entre regiões", - "training": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "waf": "Fiabilidade" + "guid": "09945bda-4333-44f2-9911-634182ba5275", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", + "service": "Defender", + "severity": "Alto", + "text": "Habilite o Gerenciamento de Postura de Segurança de Nuvem do Defender para todas as assinaturas.", + "training": "https://learn.microsoft.com/training/modules/microsoft-defender-cloud-security-posture/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "5e6c4cfd-3e50-4454-9c24-47ec66138a72", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/data-retention-archive?tabs=portal-1%2Cportal-2#how-retention-and-archiving-work", - "service": "Monitor", + "guid": "36a72a48-fffe-4c40-9747-0ab5064355ba", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", + "service": "Defender", "severity": "Alto", - "text": "Exporte logs para o Armazenamento do Azure se os requisitos de retenção de log excederem doze anos. Use o armazenamento imutável com uma política de gravação única e leitura múltipla para tornar os dados não apagáveis e não modificáveis por um intervalo especificado pelo usuário.", - "training": "https://learn.microsoft.com/learn/paths/architect-infrastructure-operations/", - "waf": "Operações" + "text": "Habilite um Plano de Proteção de Carga de Trabalho de Nuvem do Defender para Servidores em todas as assinaturas.", + "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "e7d7e484-3276-4d8b-bc05-5bcf619e8a13", - "link": "https://learn.microsoft.com/azure/governance/machine-configuration/overview", - "service": "VM", - "severity": "Média", - "text": "Monitore o descompasso de configuração da VM (máquina virtual) no nível do sistema operacional usando o Azure Policy. Habilitar os recursos de auditoria da Configuração de Computador do Gerenciamento Automatizado do Azure por meio da política ajuda as cargas de trabalho da equipe de aplicativos a consumir imediatamente os recursos de recursos com pouco esforço.", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", - "waf": "Operações" + "guid": "77425f48-ecba-43a0-aeac-a3ac733ccc6a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/connect-azure-subscription", + "service": "Defender", + "severity": "Alto", + "text": "Habilite os Planos de Proteção de Carga de Trabalho de Nuvem do Defender para Recursos do Azure em todas as assinaturas.", + "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", + "waf": "Segurança" }, { "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "f9887952-5d62-4688-9d70-ba6c97be9951", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#update-management-considerations", + "guid": "24d96b30-61ee-4436-a1cc-d6ef08bc574b", + "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", "service": "VM", - "severity": "Média", - "text": "Use o Azure Update Manager como um mecanismo de aplicação de patch para VMs Windows e Linux no Azure.", - "training": "https://learn.microsoft.com/azure/update-manager/overview?tabs=azure-vms", - "waf": "Operações" + "severity": "Alto", + "text": "Habilite o Endpoint Protection em servidores IaaS.", + "training": "https://learn.microsoft.com/training/modules/design-solutions-securing-server-client-endpoints/", + "waf": "Segurança" }, { "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "c806c048-26b7-4ddf-b4c2-b4f0c476925d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#update-management-considerations ", + "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", + "link": "https://learn.microsoft.com/azure/security-center/", "service": "VM", "severity": "Média", - "text": "Use o Gerenciador de Atualizações do Azure como um mecanismo de aplicação de patch para VMs do Windows e do Linux fora do Azure usando o Azure Arc.", - "training": "https://learn.microsoft.com/azure/update-manager/overview?tabs=azure-vms", - "waf": "Operações" - }, - { - "arm-service": "microsoft.network/networkWatchers", - "checklist": "Azure Landing Zone Review", - "guid": "90483845-c986-4cb2-a131-56a12476e49f", - "link": "https://learn.microsoft.com/azure/network-watcher/network-watcher-monitoring-overview", - "service": "Network Watcher", - "severity": "Média", - "text": "Use o Observador de Rede para monitorar proativamente os fluxos de tráfego.", - "training": "https://learn.microsoft.com/learn/modules/configure-network-watcher/", - "waf": "Operações" - }, - { - "arm-service": "Microsoft.Insights/components", - "checklist": "Azure Landing Zone Review", - "guid": "6944008b-e7d7-4e48-9327-6d8bdc055bcf", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-setup-guide/monitoring-reporting?tabs=AzureMonitor", - "service": "Monitor", - "severity": "Média", - "text": "Use os Logs do Azure Monitor para obter insights e relatórios.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-monitor/", - "waf": "Operações" - }, - { - "arm-service": "Microsoft.Insights/components", - "checklist": "Azure Landing Zone Review", - "guid": "97be9951-9048-4384-9c98-6cb2913156a1", - "link": "https://learn.microsoft.com/azure/azure-monitor/alerts/alerts-overview", - "service": "Monitor", - "severity": "Média", - "text": "Use alertas do Azure Monitor para a geração de alertas operacionais.", - "training": "https://learn.microsoft.com/training/modules/incident-response-with-alerting-on-azure/", - "waf": "Operações" + "text": "Monitore o descompasso de aplicação de patch do sistema operacional base por meio dos Logs do Azure Monitor e do Defender para Nuvem.", + "training": "https://learn.microsoft.com/training/modules/create-log-analytics-workspace-microsoft-defender-cloud/", + "waf": "Segurança" }, { "arm-service": "Microsoft.Insights/components", "checklist": "Azure Landing Zone Review", - "guid": "fed3c55f-a67e-4875-aadd-3aba3f9fde31", - "link": "https://learn.microsoft.com/azure/automation/how-to/region-mappings", + "guid": "e5f8d79f-2e87-4768-924c-516775c6ea95", + "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", "service": "Monitor", "severity": "Média", - "text": "Ao usar o Acompanhamento de Alterações e Inventário por meio de Contas de Automação do Azure, verifique se você selecionou regiões com suporte para vincular seu workspace do Log Analytics e contas de automação.", - "training": "https://learn.microsoft.com/training/modules/explore-azure-automation-devops/", - "waf": "Operações" + "text": "Conecte as configurações de recursos padrão a um workspace centralizado do Log Analytics do Azure Monitor.", + "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.RecoveryServices/vaults", "checklist": "Azure Landing Zone Review", - "guid": "eba8cf22-45c6-4dc1-9b57-2cceb3b97ce5", - "link": "https://learn.microsoft.com/azure/storage/common/storage-redundancy", - "service": "Backup", - "severity": "Baixo", - "text": "Ao usar o Backup do Azure, use os tipos de backup corretos (GRS, ZRS E LRS) para o backup, pois a configuração padrão é GRS.", - "training": "https://learn.microsoft.com/training/modules/design-solution-for-backup-disaster-recovery/", - "waf": "Fiabilidade" + "graph": "resources| where type == 'microsoft.operationalinsights/workspaces'| extend wsid = properties.customerId| project workspaceResourceId = tolower(id), name, wsid| join (resources| where type == 'microsoft.operationsmanagement/solutions'| where name has 'SecurityInsights'| extend workspaceResourceId = tostring(tolower(properties.workspaceResourceId))| project workspaceResourceId | summarize ResourceCount = count() by workspaceResourceId) on workspaceResourceId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 0)", + "guid": "a56888b2-7e83-4404-bd31-b886528502d1", + "link": "https://learn.microsoft.com/en-us/azure/well-architected/security/monitor-threats#centralized-threat-detection-with-correlated-logs", + "service": "Entra", + "severity": "Alto", + "text": "Detecção centralizada de ameaças com logs correlacionados - consolide os dados de segurança em um local central onde possam ser correlacionados em vários serviços via SIEM (gerenciamento de eventos e informações de segurança)", + "waf": "Segurança" }, { - "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "f541acdc-e979-4377-acdb-3751ab2ab13a", - "link": "https://learn.microsoft.com/azure/governance/policy/concepts/guest-configuration", - "service": "VM", + "guid": "1761e147-f65e-4d09-bbc2-f464f23e2eba", + "link": "https://learn.microsoft.com/industry/sovereignty/transparency-logs", + "service": "Entra", "severity": "Média", - "text": "Use as políticas de convidado do Azure para implantar automaticamente as configurações de software por meio de extensões de VM e impor uma configuração de VM de linha de base compatível.", + "text": "Para Zona de Destino Soberana, habilite os logs de transparência no locatário da ID do Entra.", "waf": "Segurança" }, { - "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "description": "Use os recursos de configuração de convidado do Azure Policy para auditar e corrigir as configurações do computador (por exemplo, sistema operacional, aplicativo, ambiente) para garantir que os recursos estejam alinhados com as configurações esperadas e que o Gerenciamento de Atualizações possa impor o gerenciamento de patches para VMs.", - "guid": "da6e55d7-d8a2-4adb-817d-6326af625ca4", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitoring-for-configuration-drift", - "service": "VM", + "guid": "d21a922d-5ca7-427a-82a6-35f7b21f1bfc", + "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", + "service": "Entra", "severity": "Média", - "text": "Monitore o descompasso de configuração de segurança da VM por meio do Azure Policy.", - "training": "https://learn.microsoft.com/training/paths/implement-resource-mgmt-security/", + "text": "Para Zona de Destino Soberana, habilite o Sistema de Proteção de Dados do cliente no locatário da ID do Entra.", "waf": "Segurança" }, { - "arm-service": "Microsoft.Compute/virtualMachines", + "arm-service": "Microsoft.Storage/storageAccounts", "checklist": "Azure Landing Zone Review", - "guid": "2476e49f-541a-4cdc-b979-377bcdb3751a", - "link": "https://learn.microsoft.com/azure/site-recovery/site-recovery-overview", - "service": "VM", - "severity": "Média", - "text": "Use o Azure Site Recovery para cenários de recuperação de desastre de Máquinas Virtuais do Azure para o Azure. Isso permite replicar cargas de trabalho entre regiões.", - "training": "https://learn.microsoft.com/training/modules/protect-infrastructure-with-site-recovery/", - "waf": "Operações" + "guid": "b03ed428-4617-4067-a787-85468b9ccf3f", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Storage", + "severity": "Alto", + "text": "Habilite a transferência segura para contas de armazenamento.", + "training": "https://learn.microsoft.com/training/modules/secure-azure-storage-account/", + "waf": "Segurança" }, { - "arm-service": "Microsoft.RecoveryServices/vaults", + "arm-service": "Microsoft.Storage/storageAccounts", "checklist": "Azure Landing Zone Review", - "guid": "f625ca44-e569-45f2-823a-ce8cb12308ca", - "link": "https://learn.microsoft.com/azure/backup/backup-center-overview", - "service": "Backup", - "severity": "Média", - "text": "Use recursos de backup nativos do Azure ou uma solução de backup de terceiros compatível com o Azure.", - "training": "https://learn.microsoft.com/training/modules/design-solution-for-backup-disaster-recovery/", - "waf": "Operações" + "guid": "159aac9f-863f-4f48-82cf-00c28fa97a0e", + "link": "https://learn.microsoft.com/azure/storage/blobs/data-protection-overview#recommendations-for-basic-data-protection", + "service": "Storage", + "severity": "Alto", + "text": "Habilite a exclusão reversível do contêiner para a conta de armazenamento para recuperar um contêiner excluído e seu conteúdo.", + "waf": "Segurança" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "Microsoft.KeyVault/vaults", "checklist": "Azure Landing Zone Review", - "guid": "89cc5e11-aa4d-4c3b-893d-feb99215266a", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#add-diagnostic-settings-to-save-your-wafs-logs", - "service": "WAF", + "guid": "108d5099-a11d-4445-bd8b-e12a5e95412e", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", + "service": "Key Vault", "severity": "Alto", - "text": "Adicione configurações de diagnóstico para salvar logs do WAF de serviços de entrega de aplicativos, como o Azure Front Door e o Gateway de Aplicativo do Azure. Revise regularmente os logs para verificar se há ataques e detecções de falsos positivos.", - "training": "https://learn.microsoft.com/training/modules/capture-application-logs-app-service/", - "waf": "Operações" - }, - { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", - "checklist": "Azure Landing Zone Review", - "guid": "7f408960-c626-44cb-a018-347c8d790cdf", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-best-practices#send-logs-to-microsoft-sentinel", - "service": "WAF", - "severity": "Média", - "text": "Envie logs do WAF de seus serviços de entrega de aplicativos, como o Azure Front Door e o Gateway de Aplicativo do Azure, para o Microsoft Sentinel. Detecte ataques e integre a telemetria do WAF ao seu ambiente geral do Azure.", - "training": "https://learn.microsoft.com/training/paths/sc-200-connect-logs-to-azure-sentinel/", - "waf": "Operações" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "5017f154-e3ab-4369-9829-e7e316183687", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview", - "service": "Key Vault", - "severity": "Alto", - "text": "Use o Azure Key Vault para armazenar seus segredos e credenciais.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "graph": "ResourceContainers | where type=='microsoft.resources/subscriptions'| parse id with '/subscriptions/' SubscriptionID| project subscriptionId, SubscriptionName = name| join kind=leftouter (Resources| where type == 'microsoft.keyvault/vaults'| project id, name, subscriptionId) on subscriptionId| join kind= leftouter (Resources| where type == 'microsoft.keyvault/vaults'| summarize ResourceCount = count() by subscriptionId) on subscriptionId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 1)", - "guid": "a0477a20-9945-4bda-9333-4f2491163418", - "link": "https://learn.microsoft.com/azure/key-vault/general/overview-throttling", - "service": "Key Vault", - "severity": "Média", - "text": "Use diferentes Azure Key Vaults para diferentes aplicativos e regiões para evitar limites de escala de transação e restringir o acesso a segredos.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "2ba52752-6944-4008-ae7d-7e4843276d8b", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Provisione o Azure Key Vault com as políticas de exclusão reversível e limpeza habilitadas para permitir a proteção de retenção para objetos excluídos.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "dc055bcf-619e-48a1-9f98-879525d62688", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Siga um modelo de privilégios mínimos limitando a autorização para excluir permanentemente chaves, segredos e certificados a funções personalizadas especializadas de ID do Microsoft Entra.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "6d70ba6c-97be-4995-8904-83845c986cb2", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Automatize o processo de gerenciamento e renovação de certificados com autoridades de certificação públicas para facilitar a administração.", - "training": "https://learn.microsoft.com/en-us/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "913156a1-2476-4e49-b541-acdce979377b", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Estabeleça um processo automatizado para rotação de chaves e certificados.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "cdb3751a-b2ab-413a-ba6e-55d7d8a2adb1", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Habilite o firewall e o ponto de extremidade de serviço de rede virtual ou o ponto de extremidade privado no cofre para controlar o acesso ao cofre de chaves.", - "training": "https://learn.microsoft.com/training/modules/design-implement-private-access-to-azure-services/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "17d6326a-f625-4ca4-9e56-95f2223ace8c", - "link": "https://learn.microsoft.com/azure/key-vault/general/monitor-key-vault", - "service": "Key Vault", - "severity": "Média", - "text": "Use o workspace do Log Analytics do Azure Monitor central da plataforma para auditar o uso de chave, certificado e segredo em cada instância do Key Vault.", - "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "b12308ca-5017-4f15-9e3a-b3693829e7e3", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Delegue a instanciação e o acesso privilegiado do Key Vault e use o Azure Policy para impor uma configuração consistente e compatível.", - "training": "https://learn.microsoft.com/training/modules/configure-azure-key-vault-networking-settings/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "91163418-2ba5-4275-8694-4008be7d7e48", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Use um Azure Key Vault por aplicativo por ambiente por região.", - "training": "https://learn.microsoft.com/training/modules/implement-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "25d62688-6d70-4ba6-a97b-e99519048384", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "Média", - "text": "Se você quiser trazer suas próprias chaves, isso pode não ser compatível com todos os serviços considerados. Implemente mitigação relevante para que as inconsistências não prejudiquem os resultados desejados. Escolha pares de regiões apropriados e regiões de recuperação de desastre que minimizem a latência.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "4ac6b67c-b3a4-4ff9-8e87-b07a7ce7bbdb", - "link": "https://learn.microsoft.com/industry/sovereignty/key-management", - "service": "Key Vault", - "severity": "Média", - "text": "Para a Zona de Destino Soberana, use o HSM gerenciado do Azure Key Vault para armazenar seus segredos e credenciais.", - "training": "https://learn.microsoft.com/training/modules/configure-and-manage-azure-key-vault/", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "4e5695f2-223a-4ce8-ab12-308ca5017f15", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/overview-reports", - "service": "Entra", - "severity": "Média", - "text": "Use os recursos de relatório de ID do Microsoft Entra para gerar relatórios de auditoria de controle de acesso.", - "training": "https://learn.microsoft.com/training/modules/monitor-report-aad-security-events/", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "09945bda-4333-44f2-9911-634182ba5275", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/concept-cloud-security-posture-management", - "service": "Defender", - "severity": "Alto", - "text": "Habilite o Gerenciamento de Postura de Segurança de Nuvem do Defender para todas as assinaturas.", - "training": "https://learn.microsoft.com/training/modules/microsoft-defender-cloud-security-posture/", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "36a72a48-fffe-4c40-9747-0ab5064355ba", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/plan-defender-for-servers-select-plan", - "service": "Defender", - "severity": "Alto", - "text": "Habilite um Plano de Proteção de Carga de Trabalho de Nuvem do Defender para Servidores em todas as assinaturas.", - "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "77425f48-ecba-43a0-aeac-a3ac733ccc6a", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/connect-azure-subscription", - "service": "Defender", - "severity": "Alto", - "text": "Habilite os Planos de Proteção de Carga de Trabalho de Nuvem do Defender para Recursos do Azure em todas as assinaturas.", - "training": "https://learn.microsoft.com/training/modules/understand-azure-defender-cloud-workload-protection/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Compute/virtualMachines", - "checklist": "Azure Landing Zone Review", - "guid": "24d96b30-61ee-4436-a1cc-d6ef08bc574b", - "link": "https://learn.microsoft.com/mem/configmgr/protect/deploy-use/endpoint-protection", - "service": "VM", - "severity": "Alto", - "text": "Habilite o Endpoint Protection em servidores IaaS.", - "training": "https://learn.microsoft.com/training/modules/design-solutions-securing-server-client-endpoints/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Compute/virtualMachines", - "checklist": "Azure Landing Zone Review", - "guid": "15833ee7-ad6c-46d3-9331-65c7acbe44ab", - "link": "https://learn.microsoft.com/azure/security-center/", - "service": "VM", - "severity": "Média", - "text": "Monitore o descompasso de aplicação de patch do sistema operacional base por meio dos Logs do Azure Monitor e do Defender para Nuvem.", - "training": "https://learn.microsoft.com/training/modules/create-log-analytics-workspace-microsoft-defender-cloud/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Insights/components", - "checklist": "Azure Landing Zone Review", - "guid": "e5f8d79f-2e87-4768-924c-516775c6ea95", - "link": "https://learn.microsoft.com/azure/azure-monitor/logs/design-logs-deployment", - "service": "Monitor", - "severity": "Média", - "text": "Conecte as configurações de recursos padrão a um workspace centralizado do Log Analytics do Azure Monitor.", - "training": "https://learn.microsoft.com/training/modules/analyze-infrastructure-with-azure-monitor-logs/", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.operationalinsights/workspaces'| extend wsid = properties.customerId| project workspaceResourceId = tolower(id), name, wsid| join (resources| where type == 'microsoft.operationsmanagement/solutions'| where name has 'SecurityInsights'| extend workspaceResourceId = tostring(tolower(properties.workspaceResourceId))| project workspaceResourceId | summarize ResourceCount = count() by workspaceResourceId) on workspaceResourceId| extend RCount = iff(isnull(ResourceCount), 0, ResourceCount)| project-away ResourceCount| extend compliant = (RCount <> 0)", - "guid": "a56888b2-7e83-4404-bd31-b886528502d1", - "link": "https://learn.microsoft.com/en-us/azure/well-architected/security/monitor-threats#centralized-threat-detection-with-correlated-logs", - "service": "Entra", - "severity": "Alto", - "text": "Detecção centralizada de ameaças com logs correlacionados - consolide os dados de segurança em um local central onde possam ser correlacionados em vários serviços via SIEM (gerenciamento de eventos e informações de segurança)", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "1761e147-f65e-4d09-bbc2-f464f23e2eba", - "link": "https://learn.microsoft.com/industry/sovereignty/transparency-logs", - "service": "Entra", - "severity": "Média", - "text": "Para Zona de Destino Soberana, habilite os logs de transparência no locatário da ID do Entra.", - "waf": "Segurança" - }, - { - "checklist": "Azure Landing Zone Review", - "guid": "d21a922d-5ca7-427a-82a6-35f7b21f1bfc", - "link": "https://learn.microsoft.com/azure/security/fundamentals/customer-lockbox-overview", - "service": "Entra", - "severity": "Média", - "text": "Para Zona de Destino Soberana, habilite o Sistema de Proteção de Dados do cliente no locatário da ID do Entra.", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Landing Zone Review", - "guid": "b03ed428-4617-4067-a787-85468b9ccf3f", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Storage", - "severity": "Alto", - "text": "Habilite a transferência segura para contas de armazenamento.", - "training": "https://learn.microsoft.com/training/modules/secure-azure-storage-account/", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Landing Zone Review", - "guid": "159aac9f-863f-4f48-82cf-00c28fa97a0e", - "link": "https://learn.microsoft.com/azure/storage/blobs/data-protection-overview#recommendations-for-basic-data-protection", - "service": "Storage", - "severity": "Alto", - "text": "Habilite a exclusão reversível do contêiner para a conta de armazenamento para recuperar um contêiner excluído e seu conteúdo.", - "waf": "Segurança" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Landing Zone Review", - "guid": "108d5099-a11d-4445-bd8b-e12a5e95412e", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/considerations/development-strategy-development-lifecycle#automated-builds", - "service": "Key Vault", - "severity": "Alto", - "text": "Use segredos do Key Vault para evitar codificar informações confidenciais, como credenciais (máquinas virtuais, senhas de usuário), certificados ou chaves.", - "training": "https://learn.microsoft.com/en-us/training/modules/implement-azure-key-vault/", + "text": "Use segredos do Key Vault para evitar codificar informações confidenciais, como credenciais (máquinas virtuais, senhas de usuário), certificados ou chaves.", + "training": "https://learn.microsoft.com/en-us/training/modules/implement-azure-key-vault/", "waf": "Operações" }, { @@ -8253,927 +8452,1295 @@ "link": "https://learn.microsoft.com/azure/backup/backup-overview", "service": "Azure OpenAI", "severity": "Média", - "text": "Faça backup e replique regularmente dados críticos para garantir a disponibilidade e a capacidade de recuperação dos dados em caso de perda de dados ou falhas do sistema. Aproveite os serviços de backup e recuperação de desastre do Azure para proteger seus dados.", - "waf": "Fiabilidade" + "text": "Faça backup e replique regularmente dados críticos para garantir a disponibilidade e a capacidade de recuperação dos dados em caso de perda de dados ou falhas do sistema. Aproveite os serviços de backup e recuperação de desastre do Azure para proteger seus dados.", + "waf": "Fiabilidade" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "95b96ad8-844c-4e3b-8b38-b876ba2cf204", + "link": "https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services?lang=1", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "As camadas de serviço de pesquisa de IA do Azure devem ser escolhidas para ter um SLA ", + "waf": "Fiabilidade" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "99013a5d-3ce4-474d-acbd-8682a6abca2a", + "link": "https://learn.microsoft.com/purview/purview", + "service": "Azure OpenAI", + "severity": "Baixo", + "text": "Classifique os dados e a confidencialidade, rotulando com o Microsoft Purview antes de gerar as inserções e certifique-se de tratar as inserções geradas com a mesma confidencialidade e classificação", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "4fda1dbf-3dd9-45d4-ac7c-891dca1f6d56", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/use-your-data-securely", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Criptografar dados usados para RAG com criptografia SSE/Disco com BYOK opcional", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "59ae558b-937d-4498-9e11-12dbd7ba012f", + "link": "https://learn.microsoft.com/azure/search/search-security-overview", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Certifique-se de que o TLS seja aplicado para dados em trânsito entre fontes de dados, pesquisa de IA usada para RG (Geração Aumentada por Recuperação) e comunicação LLM", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "7b94ef6e-047d-42ea-8992-b1cd6e2054b2", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/role-based-access-control", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Use o RBAC para gerenciar o acesso aos serviços do OpenAI do Azure. Atribua permissões apropriadas aos usuários e restrinja o acesso com base em suas funções e responsabilidades", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "9769e4a6-91e8-4838-ac93-6667e13c0056", + "link": "https://learn.microsoft.com/azure/security/fundamentals/data-encryption-best-practices", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Implemente técnicas de criptografia, mascaramento ou redação de dados para ocultar dados confidenciais ou substituí-los por valores ofuscados em ambientes de não produção ou ao compartilhar dados para fins de teste ou solução de problemas", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "74b1e945-b459-4837-be7a-d6c6d3b375a5", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-cloud-introduction", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Utilize o Azure Defender para detectar e responder a ameaças de segurança e configurar mecanismos de monitoramento e alerta para identificar atividades suspeitas ou violações. Aproveite o Azure Sentinel para detecção e resposta avançadas a ameaças", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "c7acbe48-abe5-44cd-99f2-e87768468c55", + "link": "https://techcommunity.microsoft.com/t5/azure-storage-blog/managing-long-term-log-retention-or-any-business-data/ba-p/2494791", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Estabeleça políticas de retenção e descarte de dados para cumprir os regulamentos de conformidade. Implemente métodos de exclusão segura para dados que não são mais necessários e mantenha uma trilha de auditoria das atividades de retenção e descarte de dados", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "a9c27d9c-42bb-46bd-8c69-99a246f3389a", + "link": "https://learn.microsoft.com/azure/ai-services/content-safety/concepts/jailbreak-detection", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Implementar proteções imediatas e detecção de aterramento usando a Segurança de conteúdo ", + "waf": "Excelência Operacional" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "a775c6ee-95b9-46ad-a844-ce3b2b38b876", + "link": "https://learn.microsoft.com/azure/compliance/", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Garanta a conformidade com os regulamentos de proteção de dados relevantes, como GDPR ou HIPAA, implementando controles de privacidade e obtendo os consentimentos ou permissões necessários para atividades de processamento de dados.", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "ba2cf204-9901-43a5-b3ce-474dccbd8682", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Eduque seus funcionários sobre as melhores práticas de segurança de dados, a importância de lidar com dados com segurança e os possíveis riscos associados a violações de dados. Incentive-os a seguir os protocolos de segurança de dados diligentemente.", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "eae01e6e-842e-452f-9721-d928c1b1cd52", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Mantenha os dados de produção separados dos dados de desenvolvimento e teste. Use apenas dados confidenciais reais na produção e utilize dados anônimos ou sintéticos em ambientes de desenvolvimento e teste.", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "1e54a29a-9de3-499c-bd7b-28dc93555620", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Se você tiver níveis variados de confidencialidade de dados, considere criar índices separados para cada nível. Por exemplo, você pode ter um índice para dados gerais e outro para dados confidenciais, cada um regido por diferentes protocolos de acesso", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "2bfe4564-b0d8-434a-948b-263e6dd60512", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Leve a segregação um passo adiante, colocando conjuntos de dados confidenciais em diferentes instâncias do serviço. Cada instância pode ser controlada com seu próprio conjunto específico de políticas RBAC", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "a36498f6-dbad-438e-ad53-cc7ce1d7aaab", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Reconheça que incorporações e vetores gerados a partir de informações confidenciais são eles próprios sensíveis. Esses dados devem receber as mesmas medidas de proteção que o material de origem", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "3571449a-b805-43d8-af89-dc7b33be2a1a", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/role-based-access-control", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Aplique o RBAC aos armazenamentos de dados com incorporações e vetores e acesso ao escopo com base nos requisitos de acesso da função", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "27f7b9e9-1be1-4f38-aef3-9812bd463cbb", + "link": "https://techcommunity.microsoft.com/t5/azure-architecture-blog/azure-openai-private-endpoints-connecting-across-vnet-s/ba-p/3913325", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Configurar o ponto de extremidade privado para serviços de IA para restringir o acesso ao serviço em sua rede", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "ac8ac199-ebb9-41a3-9d90-cae2cc881370", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Imponha um controle estrito de tráfego de entrada e saída com o Firewall do Azure e UDRs e limite os pontos de integração externos", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "6f7c0cba-fe51-4464-add4-57e927138b82", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Implemente segmentação de rede e controles de acesso para restringir o acesso ao aplicativo LLM apenas a usuários e sistemas autorizados e evitar movimentos laterais", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "7f42c78e-78cb-46a2-8ad1-90916e6a8d8f", + "link": "https://www.microsoft.com/research/blog/llmlingua-innovating-llm-efficiency-with-prompt-compression/", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Use ferramentas de compactação imediatas como LLMLingua ou gprtrim", + "waf": "Otimização de custos" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "1102cac6-eae0-41e6-b842-e52f4721d928", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/managed-identity", + "service": "Azure OpenAI", + "severity": "Alto", + "text": "Certifique-se de que as APIs e os endpoints usados pelo aplicativo LLM estejam devidamente protegidos com mecanismos de autenticação e autorização, como identidades gerenciadas, chaves de API ou OAuth, para impedir o acesso não autorizado.", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "c1b1cd52-1e54-4a29-a9de-399cfd7b28dc", + "link": "https://techcommunity.microsoft.com/t5/azure-architecture-blog/security-best-practices-for-genai-applications-openai-in-azure/ba-p/4027885", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Aplique mecanismos fortes de autenticação do usuário final, como autenticação multifator, para impedir o acesso não autorizado ao aplicativo LLM e aos recursos de rede associados", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "93555620-2bfe-4456-9b0d-834a348b263e", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Implemente ferramentas de monitoramento de rede para detectar e analisar o tráfego de rede em busca de atividades suspeitas ou maliciosas. Habilite o registro para capturar eventos de rede e facilitar a análise forense em caso de incidentes de segurança", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "6dd60512-a364-498f-9dba-d38ead53cc7c", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Realize auditorias de segurança e testes de penetração para identificar e resolver quaisquer pontos fracos ou vulnerabilidades de segurança de rede na infraestrutura de rede do aplicativo LLM", + "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "95b96ad8-844c-4e3b-8b38-b876ba2cf204", - "link": "https://www.microsoft.com/licensing/docs/view/Service-Level-Agreements-SLA-for-Online-Services?lang=1", + "guid": "e1d7aaab-3571-4449-ab80-53d89f89dc7b", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/tag-resources?tabs=json", "service": "Azure OpenAI", - "severity": "Alto", - "text": "As camadas de serviço de pesquisa de IA do Azure devem ser escolhidas para ter um SLA ", - "waf": "Fiabilidade" + "severity": "Baixo", + "text": "Os Serviços de IA do Azure são marcados corretamente para melhor gerenciamento", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "99013a5d-3ce4-474d-acbd-8682a6abca2a", - "link": "https://learn.microsoft.com/purview/purview", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations", "service": "Azure OpenAI", "severity": "Baixo", - "text": "Classifique os dados e a confidencialidade, rotulando com o Microsoft Purview antes de gerar as inserções e certifique-se de tratar as inserções geradas com a mesma confidencialidade e classificação", - "waf": "Segurança" + "text": "As contas do Serviço de IA do Azure seguem as convenções de nomenclatura organizacional", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "4fda1dbf-3dd9-45d4-ac7c-891dca1f6d56", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/use-your-data-securely", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "link": "https://learn.microsoft.com/azure/ai-services/diagnostic-logging", "service": "Azure OpenAI", "severity": "Alto", - "text": "Criptografar dados usados para RAG com criptografia SSE/Disco com BYOK opcional", - "waf": "Segurança" + "text": "Os logs de diagnóstico nos recursos de serviços de IA do Azure devem ser habilitados", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "59ae558b-937d-4498-9e11-12dbd7ba012f", - "link": "https://learn.microsoft.com/azure/search/search-security-overview", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "link": "https://learn.microsoft.com/azure/ai-services/authentication", "service": "Azure OpenAI", "severity": "Alto", - "text": "Certifique-se de que o TLS seja aplicado para dados em trânsito entre fontes de dados, pesquisa de IA usada para RG (Geração Aumentada por Recuperação) e comunicação LLM", + "text": "Recomenda-se que o acesso à chave (autenticação local) seja desabilitado por segurança. Depois de desabilitar o acesso baseado em chave, o Microsoft Entra ID se torna o único método de acesso, o que permite manter o princípio de privilégio mínimo e o controle granular. ", "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "7b94ef6e-047d-42ea-8992-b1cd6e2054b2", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/role-based-access-control", + "guid": "6b57cfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Azure OpenAI", "severity": "Alto", - "text": "Use o RBAC para gerenciar o acesso aos serviços do OpenAI do Azure. Atribua permissões apropriadas aos usuários e restrinja o acesso com base em suas funções e responsabilidades", + "text": "Armazene e gerencie chaves com segurança usando o Azure Key Vault. Evite codificar ou inserir chaves confidenciais no código do aplicativo LLM e recuperá-las com segurança do Azure Key Vault usando identidades gerenciadas", "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "9769e4a6-91e8-4838-ac93-6667e13c0056", - "link": "https://learn.microsoft.com/azure/security/fundamentals/data-encryption-best-practices", + "guid": "8b652d6c-15f5-4129-9539-8e6ded227dd1", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", "service": "Azure OpenAI", - "severity": "Média", - "text": "Implemente técnicas de criptografia, mascaramento ou redação de dados para ocultar dados confidenciais ou substituí-los por valores ofuscados em ambientes de não produção ou ao compartilhar dados para fins de teste ou solução de problemas", + "severity": "Alto", + "text": "Gire e expire regularmente as chaves armazenadas no Azure Key Vault para minimizar o risco de acesso não autorizado.", "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "74b1e945-b459-4837-be7a-d6c6d3b375a5", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-cloud-introduction", + "guid": "adfe27be-e297-401a-a352-baaab79b088d", + "link": "https://github.com/openai/tiktoken", "service": "Azure OpenAI", "severity": "Alto", - "text": "Utilize o Azure Defender para detectar e responder a ameaças de segurança e configurar mecanismos de monitoramento e alerta para identificar atividades suspeitas ou violações. Aproveite o Azure Sentinel para detecção e resposta avançadas a ameaças", - "waf": "Segurança" + "text": "Use tiktoken para entender os tamanhos de token para otimizações de token no modo de conversação", + "waf": "Otimização de custos" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "c7acbe48-abe5-44cd-99f2-e87768468c55", - "link": "https://techcommunity.microsoft.com/t5/azure-storage-blog/managing-long-term-log-retention-or-any-business-data/ba-p/2494791", + "guid": "42b06c21-d799-49a6-96f4-389a7f42c78e", + "link": "https://learn.microsoft.com/azure/security/develop/secure-dev-overview", "service": "Azure OpenAI", - "severity": "Média", - "text": "Estabeleça políticas de retenção e descarte de dados para cumprir os regulamentos de conformidade. Implemente métodos de exclusão segura para dados que não são mais necessários e mantenha uma trilha de auditoria das atividades de retenção e descarte de dados", + "severity": "Alto", + "text": "Siga práticas de codificação segura para evitar vulnerabilidades comuns, como ataques de injeção, cross-site scripting (XSS) ou configurações incorretas de segurança", "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "a9c27d9c-42bb-46bd-8c69-99a246f3389a", - "link": "https://learn.microsoft.com/azure/ai-services/content-safety/concepts/jailbreak-detection", + "guid": "78c06a73-a22a-4495-9e6a-8dc4a20e27c3", + "link": "https://learn.microsoft.com/azure/devops/repos/security/github-advanced-security-dependency-scanning?view=azure-devops", "service": "Azure OpenAI", "severity": "Alto", - "text": "Implementar proteções imediatas e detecção de aterramento usando a Segurança de conteúdo ", - "waf": "Excelência Operacional" + "text": "Configure um processo para atualizar e corrigir regularmente as bibliotecas LLM e outros componentes do sistema", + "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "a775c6ee-95b9-46ad-a844-ce3b2b38b876", - "link": "https://learn.microsoft.com/azure/compliance/", + "guid": "e29711b1-352b-4eee-879b-588defc4972c", + "link": "https://learn.microsoft.com/legal/cognitive-services/openai/code-of-conduct", "service": "Azure OpenAI", "severity": "Alto", - "text": "Garanta a conformidade com os regulamentos de proteção de dados relevantes, como GDPR ou HIPAA, implementando controles de privacidade e obtendo os consentimentos ou permissões necessários para atividades de processamento de dados.", - "waf": "Segurança" + "text": "Aderir aos termos de uso, políticas e diretrizes do Azure OpenAI ou de outros LLMs e casos de uso permitidos", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "ba2cf204-9901-43a5-b3ce-474dccbd8682", + "guid": "d3cd21bf-7703-46e5-b6b4-bed3d503547c", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs#base-series-and-codex-series-fine-tuned-models", "service": "Azure OpenAI", "severity": "Média", - "text": "Eduque seus funcionários sobre as melhores práticas de segurança de dados, a importância de lidar com dados com segurança e os possíveis riscos associados a violações de dados. Incentive-os a seguir os protocolos de segurança de dados diligentemente.", - "waf": "Segurança" + "text": "Entender a diferença no custo de modelos básicos e modelos ajustados e tamanhos de etapa de token", + "waf": "Otimização de custos" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "eae01e6e-842e-452f-9721-d928c1b1cd52", + "guid": "1347dc56-028a-471f-be1c-e15dd3f0d5e7", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/latency#batching", "service": "Azure OpenAI", "severity": "Alto", - "text": "Mantenha os dados de produção separados dos dados de desenvolvimento e teste. Use apenas dados confidenciais reais na produção e utilize dados anônimos ou sintéticos em ambientes de desenvolvimento e teste.", - "waf": "Segurança" + "text": "Solicitações em lote, sempre que possível, para minimizar a sobrecarga por chamada, o que pode reduzir os custos gerais. Certifique-se de otimizar o tamanho do lote", + "waf": "Otimização de custos" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "1e54a29a-9de3-499c-bd7b-28dc93555620", + "guid": "72d41e36-11cc-457b-9a4b-1410d43958a8", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs", "service": "Azure OpenAI", "severity": "Média", - "text": "Se você tiver níveis variados de confidencialidade de dados, considere criar índices separados para cada nível. Por exemplo, você pode ter um índice para dados gerais e outro para dados confidenciais, cada um regido por diferentes protocolos de acesso", - "waf": "Segurança" + "text": "Configure um sistema de rastreamento de custos que monitore o uso do modelo e use essas informações para ajudar a informar as escolhas do modelo e solicitar tamanhos", + "waf": "Otimização de custos" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "2bfe4564-b0d8-434a-948b-263e6dd60512", + "guid": "166cd072-af9b-4141-a898-a535e737897e", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/quota?tabs=rest#understanding-rate-limits", "service": "Azure OpenAI", "severity": "Média", - "text": "Leve a segregação um passo adiante, colocando conjuntos de dados confidenciais em diferentes instâncias do serviço. Cada instância pode ser controlada com seu próprio conjunto específico de políticas RBAC", - "waf": "Segurança" + "text": "Defina um limite máximo para o número de tokens por resposta do modelo. Otimize o tamanho para garantir que seja grande o suficiente para uma resposta válida", + "waf": "Otimização de custos" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "a36498f6-dbad-438e-ad53-cc7ce1d7aaab", + "guid": "71ca7da8-cfa9-462a-8594-946da97dc3a2", + "link": "https://learn.microsoft.com/azure/search/search-reliability", "service": "Azure OpenAI", - "severity": "Alto", - "text": "Reconheça que incorporações e vetores gerados a partir de informações confidenciais são eles próprios sensíveis. Esses dados devem receber as mesmas medidas de proteção que o material de origem", - "waf": "Segurança" + "severity": "Média", + "text": "Examine as diretrizes fornecidas sobre como configurar a pesquisa de IA para confiabilidade", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "3571449a-b805-43d8-af89-dc7b33be2a1a", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/role-based-access-control", + "guid": "3266b225-86f4-4a16-92bd-ddea8a487cde", + "link": "https://learn.microsoft.com/azure/search/vector-search-index-size?tabs=portal-vector-quota", "service": "Azure OpenAI", - "severity": "Alto", - "text": "Aplique o RBAC aos armazenamentos de dados com incorporações e vetores e acesso ao escopo com base nos requisitos de acesso da função", - "waf": "Segurança" + "severity": "Média", + "text": "Planejar e gerenciar o armazenamento de vetores do AI Search", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "27f7b9e9-1be1-4f38-aef3-9812bd463cbb", - "link": "https://techcommunity.microsoft.com/t5/azure-architecture-blog/azure-openai-private-endpoints-connecting-across-vnet-s/ba-p/3913325", + "guid": "b4861bc3-bc14-4aeb-9e66-e8d9a3aec218", + "link": "https://learn.microsoft.com/azure/machine-learning/prompt-flow/how-to-end-to-end-llmops-with-prompt-flow?view=azureml-api-2", "service": "Azure OpenAI", - "severity": "Alto", - "text": "Configurar o ponto de extremidade privado para serviços de IA para restringir o acesso ao serviço em sua rede", - "waf": "Segurança" + "severity": "Média", + "text": "Aplique as práticas do LLMOps para automatizar o gerenciamento do ciclo de vida de seus aplicativos GenAI", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "ac8ac199-ebb9-41a3-9d90-cae2cc881370", + "guid": "aa80932c-8ec9-4d1b-a770-26e5e6beba9e", + "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/provisioned-throughput-onboarding#understanding-the-provisioned-throughput-purchase-model", "service": "Azure OpenAI", "severity": "Alto", - "text": "Imponha um controle estrito de tráfego de entrada e saída com o Firewall do Azure e UDRs e limite os pontos de integração externos", - "waf": "Segurança" + "text": "Avalie o uso de modelos de faturamento - PAYG vs PTU", + "waf": "Otimização de custos" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "6f7c0cba-fe51-4464-add4-57e927138b82", + "guid": "e6436b07-36db-455f-9796-03334bdf9cc2", + "link": "https://techcommunity.microsoft.com/t5/ai-azure-ai-services-blog/how-to-control-azure-openai-models/ba-p/4146793", "service": "Azure OpenAI", - "severity": "Alto", - "text": "Implemente segmentação de rede e controles de acesso para restringir o acesso ao aplicativo LLM apenas a usuários e sistemas autorizados e evitar movimentos laterais", - "waf": "Segurança" + "severity": "Média", + "text": "Avaliar a qualidade de prompts e aplicativos ao alternar entre versões de modelo", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "7f42c78e-78cb-46a2-8ad1-90916e6a8d8f", - "link": "https://www.microsoft.com/research/blog/llmlingua-innovating-llm-efficiency-with-prompt-compression/", + "guid": "3418db61-2712-4650-9bb4-7a393a080327", + "link": "https://learn.microsoft.com/azure/machine-learning/prompt-flow/concept-model-monitoring-generative-ai-evaluation-metrics?view=azureml-api-2", "service": "Azure OpenAI", "severity": "Média", - "text": "Use ferramentas de compactação imediatas como LLMLingua ou gprtrim", - "waf": "Otimização de custos" + "text": "Avalie, monitore e refine seus aplicativos GenAI para recursos como fundamentação, relevância, precisão, coerência, fluência,", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "1102cac6-eae0-41e6-b842-e52f4721d928", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/managed-identity", + "guid": "294798b1-578b-4219-a46c-eb5443513592", "service": "Azure OpenAI", - "severity": "Alto", - "text": "Certifique-se de que as APIs e os endpoints usados pelo aplicativo LLM estejam devidamente protegidos com mecanismos de autenticação e autorização, como identidades gerenciadas, chaves de API ou OAuth, para impedir o acesso não autorizado.", - "waf": "Segurança" + "severity": "Média", + "text": "Avaliar os resultados do Azure AI Search com base em diferentes parâmetros de pesquisa", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "c1b1cd52-1e54-4a29-a9de-399cfd7b28dc", - "link": "https://techcommunity.microsoft.com/t5/azure-architecture-blog/security-best-practices-for-genai-applications-openai-in-azure/ba-p/4027885", + "guid": "2744293b-b628-4537-a551-19b08e8f5854", + "link": "https://learn.microsoft.com/azure/ai-services/openai/concepts/fine-tuning-considerations", "service": "Azure OpenAI", "severity": "Média", - "text": "Aplique mecanismos fortes de autenticação do usuário final, como autenticação multifator, para impedir o acesso não autorizado ao aplicativo LLM e aos recursos de rede associados", - "waf": "Segurança" + "text": "Olhe para os modelos de ajuste fino como forma de aumentar a precisão somente quando você tiver tentado outras abordagens básicas, como engenharia rápida e RAG com seus dados", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "93555620-2bfe-4456-9b0d-834a348b263e", + "guid": "287d9cec-166c-4d07-8af9-b141a898a535", + "link": "https://learn.microsoft.com/azure/ai-services/openai/concepts/advanced-prompt-engineering?pivots=programming-language-chat-completions", "service": "Azure OpenAI", "severity": "Média", - "text": "Implemente ferramentas de monitoramento de rede para detectar e analisar o tráfego de rede em busca de atividades suspeitas ou maliciosas. Habilite o registro para capturar eventos de rede e facilitar a análise forense em caso de incidentes de segurança", - "waf": "Segurança" + "text": "Use técnicas de engenharia rápida para melhorar a precisão das respostas do LLM", + "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "6dd60512-a364-498f-9dba-d38ead53cc7c", + "guid": "e737897e-71ca-47da-acfa-962a1594946d", + "link": "https://learn.microsoft.com/azure/ai-services/openai/concepts/red-teaming", "service": "Azure OpenAI", "severity": "Média", - "text": "Realize auditorias de segurança e testes de penetração para identificar e resolver quaisquer pontos fracos ou vulnerabilidades de segurança de rede na infraestrutura de rede do aplicativo LLM", + "text": "Equipe vermelha de seus aplicativos GenAI", "waf": "Segurança" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "e1d7aaab-3571-4449-ab80-53d89f89dc7b", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/tag-resources?tabs=json", + "guid": "edb117e6-76aa-4f66-aca4-8e5a95f2223e", + "link": "https://www.microsoft.com/haxtoolkit/guideline/encourage-granular-feedback/", "service": "Azure OpenAI", - "severity": "Baixo", - "text": "Os Serviços de IA do Azure são marcados corretamente para melhor gerenciamento", + "severity": "Média", + "text": "Forneça aos usuários finais opções de pontuação para respostas LLM e acompanhe essas pontuações. ", "waf": "Excelência Operacional" }, { "arm-service": "Microsoft.CognitiveServices/accounts", "checklist": "Azure OpenAI Review", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/resource-abbreviations", + "guid": "d5f3547c-c346-4d81-9028-a71ffe1b9b5d", + "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/optimizing-azure-openai-a-guide-to-limits-quotas-and-best/ba-p/4076268", "service": "Azure OpenAI", - "severity": "Baixo", - "text": "As contas do Serviço de IA do Azure seguem as convenções de nomenclatura organizacional", + "severity": "Alto", + "text": "Considere as práticas de gerenciamento de cotas", + "waf": "Otimização de custos" + }, + { + "arm-service": "Microsoft.CognitiveServices/accounts", + "checklist": "Azure OpenAI Review", + "guid": "9de0d5d7-31d4-41e3-911c-817bfafbc410", + "link": "https://github.com/Azure/aoai-apim/blob/main/README.md", + "service": "Azure OpenAI", + "severity": "Média", + "text": "Use soluções de balanceador de carga, como gateway baseado em APIM, para balancear carga e capacidade entre serviços e regiões", "waf": "Excelência Operacional" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "link": "https://learn.microsoft.com/azure/ai-services/diagnostic-logging", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "b32e1aa1-4813-4602-88fe-27ca2891f421", + "link": "https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/app-service-web-app/zone-redundant?source=recommendations", + "service": "App Services", + "severity": "Baixo", + "text": "Consulte a arquitetura de aplicativo Web com redundância de zona altamente disponível da linha de base para obter as práticas recomendadas", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "e4b31c6a-2e3f-4df1-8e8b-9c3aa5a27820", + "link": "https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans", + "service": "App Services", + "severity": "Média", + "text": "Use as camadas Premium e Standard. Esses níveis oferecem suporte a slots de preparo e backups automatizados.", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "a7e2e6c2-491f-4fa4-a82b-521d0bc3b202", + "link": "https://learn.microsoft.com/en-us/azure/reliability/migrate-app-service", + "service": "App Services", + "severity": "Alto", + "text": "Aproveite as zonas de disponibilidade quando aplicável regionalmente (requer a camada Premium v2 ou v3)", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "1275e4a9-7b6a-43c3-a9cd-5ee18d8995ad", + "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", + "service": "App Services", + "severity": "Média", + "text": "Implementar verificações de integridade", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "35a91c5d-4ad6-4d9b-8e0f-c47db9e6d1e7", + "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-backup", + "service": "App Services", "severity": "Alto", - "text": "Os logs de diagnóstico nos recursos de serviços de IA do Azure devem ser habilitados", - "waf": "Excelência Operacional" + "text": "Consulte as práticas recomendadas de backup e restauração para o Serviço de Aplicativo do Azure", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "link": "https://learn.microsoft.com/azure/ai-services/authentication", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "e68cd0ec-afc6-4bd8-a27f-7860ad9a0db2", + "link": "https://learn.microsoft.com/en-us/azure/architecture/framework/services/compute/azure-app-service/reliability", + "service": "App Services", "severity": "Alto", - "text": "Recomenda-se que o acesso à chave (autenticação local) seja desabilitado por segurança. Depois de desabilitar o acesso baseado em chave, o Microsoft Entra ID se torna o único método de acesso, o que permite manter o princípio de privilégio mínimo e o controle granular. ", - "waf": "Segurança" + "text": "Implementar práticas recomendadas de confiabilidade do Serviço de Aplicativo do Azure", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "6b57cfc6-5546-41e1-a3e3-453a3c863964", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Azure OpenAI", - "severity": "Alto", - "text": "Armazene e gerencie chaves com segurança usando o Azure Key Vault. Evite codificar ou inserir chaves confidenciais no código do aplicativo LLM e recuperá-las com segurança do Azure Key Vault usando identidades gerenciadas", - "waf": "Segurança" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "bd2a865c-0835-4418-bb58-4df91a5a9b3f", + "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-disaster-recovery#recover-app-content-only", + "service": "App Services", + "severity": "Baixo", + "text": "Familiarizar-se com como mover um aplicativo do Serviço de Aplicativo para outra região durante um desastre", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "8b652d6c-15f5-4129-9539-8e6ded227dd1", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "f3d2f1e4-e6d4-4b7a-a5a5-e2a9b2c6f293", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-app-service", + "service": "App Services", "severity": "Alto", - "text": "Gire e expire regularmente as chaves armazenadas no Azure Key Vault para minimizar o risco de acesso não autorizado.", - "waf": "Segurança" + "text": "Familiarizar-se com o suporte de confiabilidade no Serviço de Aplicativo do Azure", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "adfe27be-e297-401a-a352-baaab79b088d", - "link": "https://github.com/openai/tiktoken", - "service": "Azure OpenAI", - "severity": "Alto", - "text": "Use tiktoken para entender os tamanhos de token para otimizações de token no modo de conversação", - "waf": "Otimização de custos" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "c7b5f3d1-0569-4fd2-9f32-c0b64e9c0c5e", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", + "service": "App Services", + "severity": "Média", + "text": "Verifique se \"Sempre Ativo\" está habilitado para Aplicativos de Função em execução em um plano de serviço de aplicativo", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "42b06c21-d799-49a6-96f4-389a7f42c78e", - "link": "https://learn.microsoft.com/azure/security/develop/secure-dev-overview", - "service": "Azure OpenAI", - "severity": "Alto", - "text": "Siga práticas de codificação segura para evitar vulnerabilidades comuns, como ataques de injeção, cross-site scripting (XSS) ou configurações incorretas de segurança", - "waf": "Segurança" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "a3b4d5f6-758c-4f9d-9e1a-d7c6b7e8f9ab", + "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", + "service": "App Services", + "severity": "Média", + "text": "Monitorar instâncias do Serviço de Aplicativo usando verificações de integridade", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "78c06a73-a22a-4495-9e6a-8dc4a20e27c3", - "link": "https://learn.microsoft.com/azure/devops/repos/security/github-advanced-security-dependency-scanning?view=azure-devops", - "service": "Azure OpenAI", - "severity": "Alto", - "text": "Configure um processo para atualizar e corrigir regularmente as bibliotecas LLM e outros componentes do sistema", - "waf": "Segurança" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "c7d3e5f9-a19c-4833-8ca6-1dcb0128e129", + "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-overview", + "service": "App Services", + "severity": "Média", + "text": "Monitorar a disponibilidade e a capacidade de resposta do aplicativo Web ou site usando testes de disponibilidade do Application Insights", + "waf": "Fiabilidade" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "e29711b1-352b-4eee-879b-588defc4972c", - "link": "https://learn.microsoft.com/legal/cognitive-services/openai/code-of-conduct", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "b4e3f2d5-a5c6-4d7e-8b2f-c5d9e7a8f0ea", + "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-standard-tests", + "service": "App Services", + "severity": "Baixo", + "text": "Usar o teste Application Insights Standard para monitorar a disponibilidade e a capacidade de resposta do aplicativo Web ou site", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Use o Cofre de Chaves do Azure para armazenar quaisquer segredos de que o aplicativo precisa. O Cofre de Chaves fornece um ambiente seguro e auditado para armazenar segredos e está bem integrado ao Serviço de Aplicativo por meio do SDK do Cofre de Chaves ou das Referências do Cofre de Chaves do Serviço de Aplicativo.", + "guid": "834ac932-223e-4ce8-8b12-3071a5416415", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "service": "App Services", "severity": "Alto", - "text": "Aderir aos termos de uso, políticas e diretrizes do Azure OpenAI ou de outros LLMs e casos de uso permitidos", - "waf": "Excelência Operacional" + "text": "Usar o Cofre de Chaves para armazenar segredos", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "d3cd21bf-7703-46e5-b6b4-bed3d503547c", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs#base-series-and-codex-series-fine-tuned-models", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Entender a diferença no custo de modelos básicos e modelos ajustados e tamanhos de etapa de token", - "waf": "Otimização de custos" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Use uma Identidade Gerenciada para se conectar ao Cofre de Chaves usando o SDK do Cofre de Chaves ou por meio das Referências do Cofre de Chaves do Serviço de Aplicativo.", + "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "service": "App Services", + "severity": "Alto", + "text": "Usar a Identidade Gerenciada para se conectar ao Cofre de Chaves", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "1347dc56-028a-471f-be1c-e15dd3f0d5e7", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/latency#batching", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Armazene o certificado TLS do Serviço de Aplicativo no Cofre de Chaves.", + "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", + "service": "App Services", "severity": "Alto", - "text": "Solicitações em lote, sempre que possível, para minimizar a sobrecarga por chamada, o que pode reduzir os custos gerais. Certifique-se de otimizar o tamanho do lote", - "waf": "Otimização de custos" + "text": "Use o Cofre de Chaves para armazenar o certificado TLS.", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "72d41e36-11cc-457b-9a4b-1410d43958a8", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/manage-costs", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Os sistemas que processam informações confidenciais devem ser isolados. Para fazer isso, use Planos do Serviço de Aplicativo ou Ambientes do Serviço de Aplicativo separados e considere o uso de assinaturas ou grupos de gerenciamento diferentes.", + "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", + "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", + "service": "App Services", "severity": "Média", - "text": "Configure um sistema de rastreamento de custos que monitore o uso do modelo e use essas informações para ajudar a informar as escolhas do modelo e solicitar tamanhos", - "waf": "Otimização de custos" + "text": "Isolar sistemas que processam informações confidenciais", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "166cd072-af9b-4141-a898-a535e737897e", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/quota?tabs=rest#understanding-rate-limits", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Os discos locais no Serviço de Aplicativo não são criptografados e os dados confidenciais não devem ser armazenados neles. (Por exemplo: D:\\\\Local e %TMP%).", + "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", + "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", + "service": "App Services", "severity": "Média", - "text": "Defina um limite máximo para o número de tokens por resposta do modelo. Otimize o tamanho para garantir que seja grande o suficiente para uma resposta válida", - "waf": "Otimização de custos" + "text": "Não armazene dados confidenciais no disco local", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "71ca7da8-cfa9-462a-8594-946da97dc3a2", - "link": "https://learn.microsoft.com/azure/search/search-reliability", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Para aplicativos Web autenticados, use um Provedor de Identidade bem estabelecido, como o Azure AD ou o Azure AD B2C. Aproveite a estrutura de aplicativo de sua escolha para se integrar a esse provedor ou use o recurso de Autenticação/Autorização do Serviço de Aplicativo.", + "guid": "919ca0b2-c121-459e-814b-933df574eccc", + "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", + "service": "App Services", "severity": "Média", - "text": "Examine as diretrizes fornecidas sobre como configurar a pesquisa de IA para confiabilidade", - "waf": "Excelência Operacional" + "text": "Usar um provedor de identidade estabelecido para autenticação", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "3266b225-86f4-4a16-92bd-ddea8a487cde", - "link": "https://learn.microsoft.com/azure/search/vector-search-index-size?tabs=portal-vector-quota", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Planejar e gerenciar o armazenamento de vetores do AI Search", - "waf": "Excelência Operacional" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Implante código no Serviço de Aplicativo a partir de um ambiente controlado e confiável, como um pipeline de implantação de DevOps bem gerenciado e seguro. Isso evita que o código que não foi controlado por versão e verificado para ser implantado a partir de um host mal-intencionado.", + "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", + "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", + "service": "App Services", + "severity": "Alto", + "text": "Implantar a partir de um ambiente confiável", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "b4861bc3-bc14-4aeb-9e66-e8d9a3aec218", - "link": "https://learn.microsoft.com/azure/machine-learning/prompt-flow/how-to-end-to-end-llmops-with-prompt-flow?view=azureml-api-2", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Aplique as práticas do LLMOps para automatizar o gerenciamento do ciclo de vida de seus aplicativos GenAI", - "waf": "Excelência Operacional" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Desative a autenticação básica para FTP/FTPS e WebDeploy/SCM. Isso desabilita o acesso a esses serviços e impõe o uso de pontos de extremidade protegidos do Azure AD para implantação. Observe que o site do SCM também pode ser aberto usando credenciais do Azure AD.", + "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", + "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", + "service": "App Services", + "severity": "Alto", + "text": "Desabilitar a autenticação básica", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "aa80932c-8ec9-4d1b-a770-26e5e6beba9e", - "link": "https://learn.microsoft.com/azure/ai-services/openai/how-to/provisioned-throughput-onboarding#understanding-the-provisioned-throughput-purchase-model", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Sempre que possível, use a Identidade Gerenciada para se conectar aos recursos protegidos do Azure AD. Se isso não for possível, armazene segredos no Cofre de Chaves e conecte-se ao Cofre de Chaves usando uma Identidade Gerenciada.", + "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", + "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", + "service": "App Services", "severity": "Alto", - "text": "Avalie o uso de modelos de faturamento - PAYG vs PTU", - "waf": "Otimização de custos" + "text": "Usar a Identidade Gerenciada para se conectar a recursos", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "e6436b07-36db-455f-9796-03334bdf9cc2", - "link": "https://techcommunity.microsoft.com/t5/ai-azure-ai-services-blog/how-to-control-azure-openai-models/ba-p/4146793", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Avaliar a qualidade de prompts e aplicativos ao alternar entre versões de modelo", - "waf": "Excelência Operacional" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Onde estiver usando imagens armazenadas no Registro de Contêiner do Azure, extraia-as usando uma Identidade Gerenciada.", + "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", + "service": "App Services", + "severity": "Alto", + "text": "Extrair contêineres usando uma identidade gerenciada", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "3418db61-2712-4650-9bb4-7a393a080327", - "link": "https://learn.microsoft.com/azure/machine-learning/prompt-flow/concept-model-monitoring-generative-ai-evaluation-metrics?view=azureml-api-2", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Ao definir as configurações de diagnóstico do Serviço de Aplicativo, você pode enviar toda a telemetria para o Log Analytics como o destino central para registro em log e monitoramento. Isso permite que você monitore a atividade de tempo de execução do Serviço de Aplicativo, como logs HTTP, logs de aplicativos, logs de plataforma, ...", + "guid": "47768314-c115-4775-a2ea-55b46ad48408", + "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", + "service": "App Services", "severity": "Média", - "text": "Avalie, monitore e refine seus aplicativos GenAI para recursos como fundamentação, relevância, precisão, coerência, fluência,", - "waf": "Excelência Operacional" + "text": "Enviar logs de tempo de execução do Serviço de Aplicativo para o Log Analytics", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "294798b1-578b-4219-a46c-eb5443513592", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Configure uma configuração de diagnóstico para enviar o log de atividades para o Log Analytics como o destino central para registro e monitoramento. Isso permite que você monitore a atividade do plano de controle no próprio recurso do Serviço de Aplicativo.", + "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "service": "App Services", "severity": "Média", - "text": "Avaliar os resultados do Azure AI Search com base em diferentes parâmetros de pesquisa", - "waf": "Excelência Operacional" + "text": "Enviar logs de atividade do Serviço de Aplicativo para o Log Analytics", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "2744293b-b628-4537-a551-19b08e8f5854", - "link": "https://learn.microsoft.com/azure/ai-services/openai/concepts/fine-tuning-considerations", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Controle o acesso à rede de saída usando uma combinação de integração regional de VNet, grupos de segurança de rede e UDR's. O tráfego deve ser roteado para um NVA, como o Firewall do Azure. Certifique-se de monitorar os logs do Firewall.", + "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", + "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", + "service": "App Services", "severity": "Média", - "text": "Olhe para os modelos de ajuste fino como forma de aumentar a precisão somente quando você tiver tentado outras abordagens básicas, como engenharia rápida e RAG com seus dados", - "waf": "Excelência Operacional" + "text": "O acesso à rede de saída deve ser controlado", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "287d9cec-166c-4d07-8af9-b141a898a535", - "link": "https://learn.microsoft.com/azure/ai-services/openai/concepts/advanced-prompt-engineering?pivots=programming-language-chat-completions", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Use técnicas de engenharia rápida para melhorar a precisão das respostas do LLM", - "waf": "Excelência Operacional" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Você pode fornecer um IP de saída estável usando a integração de rede virtual e um gateway NAT de rede virtual ou um NVA como o Firewall do Azure. Isso permite que a parte receptora permita uma lista com base no IP, caso seja necessário. Observe que, para comunicações com os Serviços do Azure, geralmente não há necessidade de depender do endereço IP e mecânicas como Pontos de Extremidade de Serviço devem ser usadas. (Além disso, o uso de pontos de extremidade privados na extremidade de recebimento evita que o SNAT aconteça e fornece um intervalo de IP de saída estável.)", + "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", + "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", + "service": "App Services", + "severity": "Baixo", + "text": "Garantir um IP estável para comunicações de saída para endereços de Internet", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "e737897e-71ca-47da-acfa-962a1594946d", - "link": "https://learn.microsoft.com/azure/ai-services/openai/concepts/red-teaming", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Equipe vermelha de seus aplicativos GenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Controle o acesso à rede de entrada usando uma combinação de Restrições de Acesso do Serviço de Aplicativo, Pontos de Extremidade de Serviço ou Pontos de Extremidade Privados. Diferentes restrições de acesso podem ser necessárias e configuradas para o próprio aplicativo Web e o site do SCM.", + "guid": "0725769e-e669-41a4-a34a-c932223ece80", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "service": "App Services", + "severity": "Alto", + "text": "O acesso à rede de entrada deve ser controlado", "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "edb117e6-76aa-4f66-aca4-8e5a95f2223e", - "link": "https://www.microsoft.com/haxtoolkit/guideline/encourage-granular-feedback/", - "service": "Azure OpenAI", - "severity": "Média", - "text": "Forneça aos usuários finais opções de pontuação para respostas LLM e acompanhe essas pontuações. ", - "waf": "Excelência Operacional" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Proteja-se contra tráfego de entrada mal-intencionado usando um Firewall de Aplicativo Web, como o Gateway de Aplicativo ou o Azure Front Door. Certifique-se de monitorar os logs do WAF.", + "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", + "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", + "service": "App Services", + "severity": "Alto", + "text": "Usar um WAF na frente do Serviço de Aplicativo", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "d5f3547c-c346-4d81-9028-a71ffe1b9b5d", - "link": "https://techcommunity.microsoft.com/t5/fasttrack-for-azure/optimizing-azure-openai-a-guide-to-limits-quotas-and-best/ba-p/4076268", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Certifique-se de que o WAF não pode ser ignorado bloqueando o acesso apenas ao WAF. Use uma combinação de Restrições de Acesso, Pontos de Extremidade de Serviço e Pontos de Extremidade Privados.", + "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "service": "App Services", "severity": "Alto", - "text": "Considere as práticas de gerenciamento de cotas", - "waf": "Otimização de custos" + "text": "Evite que o WAF seja ignorado", + "waf": "Segurança" }, { - "arm-service": "Microsoft.CognitiveServices/accounts", - "checklist": "Azure OpenAI Review", - "guid": "9de0d5d7-31d4-41e3-911c-817bfafbc410", - "link": "https://github.com/Azure/aoai-apim/blob/main/README.md", - "service": "Azure OpenAI", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Defina a política TLS mínima como 1.2 na configuração do Serviço de Aplicativo.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", + "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", + "service": "App Services", "severity": "Média", - "text": "Use soluções de balanceador de carga, como gateway baseado em APIM, para balancear carga e capacidade entre serviços e regiões", - "waf": "Excelência Operacional" + "text": "Definir a política TLS mínima como 1.2", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "b32e1aa1-4813-4602-88fe-27ca2891f421", - "link": "https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/app-service-web-app/zone-redundant?source=recommendations", + "description": "Configure o Serviço de Aplicativo para usar somente HTTPS. Isso faz com que o Serviço de Aplicativo redirecione de HTTP para HTTPS. Considere fortemente o uso de HTTP Strict Transport Security (HSTS) em seu código ou a partir de seu WAF, que informa aos navegadores que o site só deve ser acessado usando HTTPS.", + "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", + "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", "service": "App Services", - "severity": "Baixo", - "text": "Consulte a arquitetura de aplicativo Web com redundância de zona altamente disponível da linha de base para obter as práticas recomendadas", - "waf": "Fiabilidade" + "severity": "Alto", + "text": "Usar somente HTTPS", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "e4b31c6a-2e3f-4df1-8e8b-9c3aa5a27820", - "link": "https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans", + "description": "Não use curingas em sua configuração do CORS, pois isso permite que todas as origens acessem o serviço (derrotando assim o propósito do CORS). Especificamente, permita apenas as origens que você espera poder acessar o serviço.", + "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", + "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", "service": "App Services", - "severity": "Média", - "text": "Use as camadas Premium e Standard. Esses níveis oferecem suporte a slots de preparo e backups automatizados.", - "waf": "Fiabilidade" + "severity": "Alto", + "text": "Curingas não devem ser usados para CORS", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "a7e2e6c2-491f-4fa4-a82b-521d0bc3b202", - "link": "https://learn.microsoft.com/en-us/azure/reliability/migrate-app-service", + "description": "A depuração remota não deve ser ativada na produção, pois isso abre portas adicionais no serviço, o que aumenta a superfície de ataque. Observe que o serviço ativa a depuração remota automaticamente após 48 horas.", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", + "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", + "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", "service": "App Services", "severity": "Alto", - "text": "Aproveite as zonas de disponibilidade quando aplicável regionalmente (requer a camada Premium v2 ou v3)", - "waf": "Fiabilidade" + "text": "Desativar a depuração remota", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "1275e4a9-7b6a-43c3-a9cd-5ee18d8995ad", - "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", + "description": "Habilite o Defender para o Serviço de Aplicativo. Isso (entre outras ameaças) detecta comunicações com endereços IP mal-intencionados conhecidos. Analise as recomendações do Defender for App Service como parte de suas operações.", + "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", "service": "App Services", "severity": "Média", - "text": "Implementar verificações de integridade", - "waf": "Fiabilidade" + "text": "Habilitar o Defender for Cloud - Defender for App Service", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "35a91c5d-4ad6-4d9b-8e0f-c47db9e6d1e7", - "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-backup", + "description": "O Azure fornece proteção contra DDoS Basic em sua rede, que pode ser aprimorada com recursos inteligentes de DDoS Standard que aprendem sobre padrões normais de tráfego e podem detectar comportamentos incomuns. O DDoS Standard se aplica a uma Rede Virtual, portanto, ele deve ser configurado para o recurso de rede na frente do aplicativo, como o Application Gateway ou um NVA.", + "guid": "223ece80-b123-4071-a541-6415833ea3ad", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", "service": "App Services", - "severity": "Alto", - "text": "Consulte as práticas recomendadas de backup e restauração para o Serviço de Aplicativo do Azure", - "waf": "Fiabilidade" + "severity": "Média", + "text": "Habilitar o padrão de proteção DDOS na rede virtual WAF", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "e68cd0ec-afc6-4bd8-a27f-7860ad9a0db2", - "link": "https://learn.microsoft.com/en-us/azure/architecture/framework/services/compute/azure-app-service/reliability", + "description": "Ao usar imagens armazenadas no Registro de Contêiner do Azure, extraia-as por uma rede virtual do Registro de Contêiner do Azure usando seu ponto de extremidade privado e a configuração do aplicativo 'WEBSITE_PULL_IMAGE_OVER_VNET'.", + "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", "service": "App Services", - "severity": "Alto", - "text": "Implementar práticas recomendadas de confiabilidade do Serviço de Aplicativo do Azure", - "waf": "Fiabilidade" + "severity": "Média", + "text": "Extrair contêineres por uma rede virtual", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "bd2a865c-0835-4418-bb58-4df91a5a9b3f", - "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-disaster-recovery#recover-app-content-only", + "description": "Realizar um teste de penetração na aplicação web seguindo as regras de teste de penetração de engajamento.", + "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", + "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", "service": "App Services", - "severity": "Baixo", - "text": "Familiarizar-se com como mover um aplicativo do Serviço de Aplicativo para outra região durante um desastre", - "waf": "Fiabilidade" + "severity": "Média", + "text": "Realizar um teste de penetração", + "waf": "Segurança" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "guid": "f3d2f1e4-e6d4-4b7a-a5a5-e2a9b2c6f293", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-app-service", + "description": "Implante código confiável que foi validado e verificado em busca de vulnerabilidades de acordo com as práticas de DevSecOps.", + "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", + "service": "App Services", + "severity": "Média", + "text": "Implantar código validado", + "waf": "Segurança" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Use as versões mais recentes de plataformas, linguagens de programação, protocolos e estruturas suportadas.", + "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", + "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", "service": "App Services", "severity": "Alto", - "text": "Familiarizar-se com o suporte de confiabilidade no Serviço de Aplicativo do Azure", - "waf": "Fiabilidade" + "text": "Use plataformas, linguagens, protocolos e frameworks atualizados", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Aplicar as orientações do benchmark de segurança na nuvem da Microsoft relacionadas ao armazenamento", + "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", + "service": "Azure Storage", + "severity": "Média", + "text": "Considere a 'linha de base de segurança do Azure para armazenamento'", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "O Armazenamento do Azure, por padrão, tem um endereço IP público e pode ser acessado pela Internet. Os pontos de extremidade privados permitem expor com segurança o Armazenamento do Azure apenas aos recursos de Computação do Azure que precisam de acesso, eliminando assim a exposição à Internet pública", + "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", + "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere o uso de pontos de extremidade privados para o Armazenamento do Azure", + "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "c7b5f3d1-0569-4fd2-9f32-c0b64e9c0c5e", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "As contas de armazenamento recém-criadas são criadas usando o modelo de implantação ARM, para que o RBAC, a auditoria, etc., estejam todos habilitados. Verifique se não há contas de armazenamento antigas com modelo de implantação clássico em uma assinatura", + "guid": "30e37c3e-2971-41b2-963c-eee079b598de", + "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", + "service": "Azure Storage", "severity": "Média", - "text": "Verifique se \"Sempre Ativo\" está habilitado para Aplicativos de Função em execução em um plano de serviço de aplicativo", - "waf": "Fiabilidade" + "text": "Verifique se as contas de armazenamento mais antigas não estão usando o 'modelo de implantação clássico'", + "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "a3b4d5f6-758c-4f9d-9e1a-d7c6b7e8f9ab", - "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", - "service": "App Services", - "severity": "Média", - "text": "Monitorar instâncias do Serviço de Aplicativo usando verificações de integridade", - "waf": "Fiabilidade" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Aproveite o Microsoft Defender para saber mais sobre atividades suspeitas e configurações incorretas.", + "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", + "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", + "service": "Azure Storage", + "severity": "Alto", + "text": "Habilitar o Microsoft Defender para todas as suas contas de armazenamento", + "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "c7d3e5f9-a19c-4833-8ca6-1dcb0128e129", - "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-overview", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "O mecanismo soft-delete permite recuperar blobs excluídos acidentalmente.", + "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", + "service": "Azure Storage", "severity": "Média", - "text": "Monitorar a disponibilidade e a capacidade de resposta do aplicativo Web ou site usando testes de disponibilidade do Application Insights", - "waf": "Fiabilidade" + "text": "Ativar 'exclusão suave' para blobs", + "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "b4e3f2d5-a5c6-4d7e-8b2f-c5d9e7a8f0ea", - "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-standard-tests", - "service": "App Services", - "severity": "Baixo", - "text": "Usar o teste Application Insights Standard para monitorar a disponibilidade e a capacidade de resposta do aplicativo Web ou site", - "waf": "Fiabilidade" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere desativar seletivamente a \"exclusão suave\" para determinados contêineres de blob, por exemplo, se o aplicativo tiver que garantir que as informações excluídas sejam imediatamente excluídas, por exemplo, por motivos de confidencialidade, privacidade ou conformidade. ", + "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "service": "Azure Storage", + "severity": "Média", + "text": "Desativar 'exclusão suave' para blobs", + "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Use o Cofre de Chaves do Azure para armazenar quaisquer segredos de que o aplicativo precisa. O Cofre de Chaves fornece um ambiente seguro e auditado para armazenar segredos e está bem integrado ao Serviço de Aplicativo por meio do SDK do Cofre de Chaves ou das Referências do Cofre de Chaves do Serviço de Aplicativo.", - "guid": "834ac932-223e-4ce8-8b12-3071a5416415", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "A exclusão suave para contêineres permite que você recupere um contêiner depois que ele tenha sido excluído, por exemplo, recuperar de uma operação de exclusão acidental.", + "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", + "service": "Azure Storage", "severity": "Alto", - "text": "Usar o Cofre de Chaves para armazenar segredos", + "text": "Ativar 'exclusão suave' para contêineres", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Use uma Identidade Gerenciada para se conectar ao Cofre de Chaves usando o SDK do Cofre de Chaves ou por meio das Referências do Cofre de Chaves do Serviço de Aplicativo.", - "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere desativar seletivamente a \"exclusão suave\" para determinados contêineres de blob, por exemplo, se o aplicativo tiver que garantir que as informações excluídas sejam imediatamente excluídas, por exemplo, por motivos de confidencialidade, privacidade ou conformidade. ", + "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "service": "Azure Storage", + "severity": "Média", + "text": "Desativar 'exclusão suave' para contêineres", + "waf": "Segurança" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Evita a exclusão acidental de uma conta de armazenamento, forçando o usuário a remover primeiro o bloqueio de exclusão, antes da exclusão", + "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "service": "Azure Storage", "severity": "Alto", - "text": "Usar a Identidade Gerenciada para se conectar ao Cofre de Chaves", + "text": "Habilitar bloqueios de recursos em contas de armazenamento", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Armazene o certificado TLS do Serviço de Aplicativo no Cofre de Chaves.", - "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere políticas de \"retenção legal\" ou \"retenção baseada em tempo\" para blobs, de modo que seja impossível excluir o blob, o contêiner ou a conta de armazenamento. Por favor, note que \"impossível\" significa na verdade \"impossível\"; uma vez que uma conta de armazenamento contém um blob imutável, a única maneira de 'se livrar' dessa conta de armazenamento é cancelando a assinatura do Azure.", + "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", + "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", + "service": "Azure Storage", "severity": "Alto", - "text": "Use o Cofre de Chaves para armazenar o certificado TLS.", + "text": "Considere blobs imutáveis", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Os sistemas que processam informações confidenciais devem ser isolados. Para fazer isso, use Planos do Serviço de Aplicativo ou Ambientes do Serviço de Aplicativo separados e considere o uso de assinaturas ou grupos de gerenciamento diferentes.", - "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", - "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", - "service": "App Services", - "severity": "Média", - "text": "Isolar sistemas que processam informações confidenciais", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Considere desabilitar o acesso HTTP/80 desprotegido à conta de armazenamento, para que todas as transferências de dados sejam criptografadas, protegidas por integridade e o servidor seja autenticado. ", + "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Azure Storage", + "severity": "Alto", + "text": "Exigir HTTPS, ou seja, desativar a porta 80 na conta de armazenamento", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Os discos locais no Serviço de Aplicativo não são criptografados e os dados confidenciais não devem ser armazenados neles. (Por exemplo: D:\\\\Local e %TMP%).", - "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", - "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", - "service": "App Services", - "severity": "Média", - "text": "Não armazene dados confidenciais no disco local", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Ao configurar um domínio personalizado (nome do host) em uma conta de armazenamento, verifique se você precisa de TLS/HTTPS; em caso afirmativo, talvez seja necessário colocar a CDN do Azure na frente da sua conta de armazenamento.", + "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", + "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", + "service": "Azure Storage", + "severity": "Alto", + "text": "Ao impor HTTPS (desabilitando HTTP), verifique se você não usa domínios personalizados (CNAME) para a conta de armazenamento.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Para aplicativos Web autenticados, use um Provedor de Identidade bem estabelecido, como o Azure AD ou o Azure AD B2C. Aproveite a estrutura de aplicativo de sua escolha para se integrar a esse provedor ou use o recurso de Autenticação/Autorização do Serviço de Aplicativo.", - "guid": "919ca0b2-c121-459e-814b-933df574eccc", - "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Exigir HTTPS quando um cliente usa um token SAS para acessar dados de blob ajuda a minimizar o risco de perda de credenciais.", + "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", + "service": "Azure Storage", "severity": "Média", - "text": "Usar um provedor de identidade estabelecido para autenticação", + "text": "Limitar tokens de assinatura de acesso compartilhado (SAS) somente a conexões HTTPS", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Implante código no Serviço de Aplicativo a partir de um ambiente controlado e confiável, como um pipeline de implantação de DevOps bem gerenciado e seguro. Isso evita que o código que não foi controlado por versão e verificado para ser implantado a partir de um host mal-intencionado.", - "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", - "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Os tokens AAD devem ser favorecidos em relação às assinaturas de acesso compartilhado, sempre que possível", + "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", + "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", + "service": "Azure Storage", "severity": "Alto", - "text": "Implantar a partir de um ambiente confiável", + "text": "Usar tokens do Azure Active Directory (Azure AD) para acesso de blob", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Desative a autenticação básica para FTP/FTPS e WebDeploy/SCM. Isso desabilita o acesso a esses serviços e impõe o uso de pontos de extremidade protegidos do Azure AD para implantação. Observe que o site do SCM também pode ser aberto usando credenciais do Azure AD.", - "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", - "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", - "service": "App Services", - "severity": "Alto", - "text": "Desabilitar a autenticação básica", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Ao atribuir uma função a um usuário, grupo ou aplicativo, conceda a essa entidade de segurança apenas as permissões necessárias para que eles executem suas tarefas. Limitar o acesso aos recursos ajuda a evitar o uso indevido não intencional e mal-intencionado de seus dados.", + "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", + "service": "Azure Storage", + "severity": "Média", + "text": "Privilégio mínimo nas permissões do IaM", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Sempre que possível, use a Identidade Gerenciada para se conectar aos recursos protegidos do Azure AD. Se isso não for possível, armazene segredos no Cofre de Chaves e conecte-se ao Cofre de Chaves usando uma Identidade Gerenciada.", - "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", - "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Uma SAS de delegação de usuário é protegida com credenciais do Azure Active Directory (Azure AD) e também pelas permissões especificadas para a SAS. Uma SAS de delegação de usuário é análoga a uma SAS de serviço em termos de escopo e função, mas oferece benefícios de segurança em relação à SAS de serviço. ", + "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", + "service": "Azure Storage", "severity": "Alto", - "text": "Usar a Identidade Gerenciada para se conectar a recursos", + "text": "Ao usar o SAS, prefira o SAS de delegação de usuário ao SAS baseado em chave de conta de armazenamento.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Onde estiver usando imagens armazenadas no Registro de Contêiner do Azure, extraia-as usando uma Identidade Gerenciada.", - "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "As chaves de conta de armazenamento ('chaves compartilhadas') têm pouquíssimos recursos de auditoria. Embora possa ser monitorado em quem/quando foi obtida uma cópia das chaves, uma vez que as chaves estão nas mãos de várias pessoas, é impossível atribuir o uso a um usuário específico. Depender exclusivamente da autenticação do AAD facilita a vinculação do acesso ao armazenamento a um usuário. ", + "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", + "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", + "service": "Azure Storage", "severity": "Alto", - "text": "Extrair contêineres usando uma identidade gerenciada", + "text": "Considere desabilitar as chaves de conta de armazenamento, para que somente o acesso ao AAD (e a delegação de usuários SAS) seja suportado.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Ao definir as configurações de diagnóstico do Serviço de Aplicativo, você pode enviar toda a telemetria para o Log Analytics como o destino central para registro em log e monitoramento. Isso permite que você monitore a atividade de tempo de execução do Serviço de Aplicativo, como logs HTTP, logs de aplicativos, logs de plataforma, ...", - "guid": "47768314-c115-4775-a2ea-55b46ad48408", - "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", - "service": "App Services", - "severity": "Média", - "text": "Enviar logs de tempo de execução do Serviço de Aplicativo para o Log Analytics", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Use os dados do Registro de atividades para identificar \"quando\", \"quem\", \"o que\" e \"como\" a segurança da sua conta de armazenamento está sendo visualizada ou alterada (ou seja, chaves de conta de armazenamento, políticas de acesso, etc.).", + "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", + "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", + "service": "Azure Storage", + "severity": "Alto", + "text": "Considere usar o Azure Monitor para auditar as operações do plano de controle na conta de armazenamento", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Configure uma configuração de diagnóstico para enviar o log de atividades para o Log Analytics como o destino central para registro e monitoramento. Isso permite que você monitore a atividade do plano de controle no próprio recurso do Serviço de Aplicativo.", - "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Uma política de expiração de chave permite que você defina um lembrete para a rotação das chaves de acesso da conta. O lembrete será exibido se o intervalo especificado tiver decorrido e as teclas ainda não tiverem sido giradas.", + "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", + "service": "Azure Storage", "severity": "Média", - "text": "Enviar logs de atividade do Serviço de Aplicativo para o Log Analytics", + "text": "Ao usar chaves de conta de armazenamento, considere habilitar uma 'política de expiração de chave'", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Controle o acesso à rede de saída usando uma combinação de integração regional de VNet, grupos de segurança de rede e UDR's. O tráfego deve ser roteado para um NVA, como o Firewall do Azure. Certifique-se de monitorar os logs do Firewall.", - "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", - "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Uma diretiva de expiração SAS especifica um intervalo recomendado sobre o qual a SAS é válida. As políticas de expiração do SAS se aplicam a um SAS de serviço ou a um SAS de conta. Quando um usuário gera SAS de serviço ou SAS de conta com um intervalo de validade maior do que o intervalo recomendado, ele verá um aviso.", + "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", + "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", + "service": "Azure Storage", "severity": "Média", - "text": "O acesso à rede de saída deve ser controlado", + "text": "Considere configurar uma política de expiração SAS", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Você pode fornecer um IP de saída estável usando a integração de rede virtual e um gateway NAT de rede virtual ou um NVA como o Firewall do Azure. Isso permite que a parte receptora permita uma lista com base no IP, caso seja necessário. Observe que, para comunicações com os Serviços do Azure, geralmente não há necessidade de depender do endereço IP e mecânicas como Pontos de Extremidade de Serviço devem ser usadas. (Além disso, o uso de pontos de extremidade privados na extremidade de recebimento evita que o SNAT aconteça e fornece um intervalo de IP de saída estável.)", - "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", - "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", - "service": "App Services", - "severity": "Baixo", - "text": "Garantir um IP estável para comunicações de saída para endereços de Internet", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "As políticas de acesso armazenado oferecem a opção de revogar permissões para uma SAS de serviço sem precisar gerar novamente as chaves da conta de armazenamento. ", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", + "service": "Azure Storage", + "severity": "Média", + "text": "Considere vincular o SAS a uma política de acesso armazenado", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Controle o acesso à rede de entrada usando uma combinação de Restrições de Acesso do Serviço de Aplicativo, Pontos de Extremidade de Serviço ou Pontos de Extremidade Privados. Diferentes restrições de acesso podem ser necessárias e configuradas para o próprio aplicativo Web e o site do SCM.", - "guid": "0725769e-e669-41a4-a34a-c932223ece80", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", - "service": "App Services", - "severity": "Alto", - "text": "O acesso à rede de entrada deve ser controlado", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", + "service": "Azure Storage", + "severity": "Média", + "text": "Considere configurar o repositório de código-fonte do aplicativo para detectar cadeias de conexão com check-in e chaves de conta de armazenamento.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Proteja-se contra tráfego de entrada mal-intencionado usando um Firewall de Aplicativo Web, como o Gateway de Aplicativo ou o Azure Front Door. Certifique-se de monitorar os logs do WAF.", - "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", - "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Idealmente, seu aplicativo deve estar usando uma identidade gerenciada para autenticar no Armazenamento do Azure. Se isso não for possível, considere ter a credencial de armazenamento (cadeia de conexão, chave de conta de armazenamento, SAS, credencial da entidade de serviço) no Azure KeyVault ou em um serviço equivalente.", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", + "service": "Azure Storage", "severity": "Alto", - "text": "Usar um WAF na frente do Serviço de Aplicativo", + "text": "Considere armazenar cadeias de conexão no Cofre de Chaves do Azure (em cenários em que identidades gerenciadas não são possíveis)", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Certifique-se de que o WAF não pode ser ignorado bloqueando o acesso apenas ao WAF. Use uma combinação de Restrições de Acesso, Pontos de Extremidade de Serviço e Pontos de Extremidade Privados.", - "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Use tempos de expiração de curto prazo em um SAS de serviço SAS ad hoc ou SAS de conta. Dessa forma, mesmo que um SAS seja comprometido, ele é válido apenas por um curto período de tempo. Essa prática é especialmente importante se você não puder fazer referência a uma política de acesso armazenado. Os tempos de expiração de curto prazo também limitam a quantidade de dados que podem ser gravados em um blob, limitando o tempo disponível para carregar nele.", + "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", "severity": "Alto", - "text": "Evite que o WAF seja ignorado", + "text": "Esforce-se por curtos períodos de validade para SAS ad-hoc", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Defina a política TLS mínima como 1.2 na configuração do Serviço de Aplicativo.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", - "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Ao criar um SAS, seja o mais específico e restritivo possível. Prefira um SAS para um único recurso e operação em vez de um SAS que dá acesso muito mais amplo.", + "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", "severity": "Média", - "text": "Definir a política TLS mínima como 1.2", + "text": "Aplicar um escopo restrito a uma SAS", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Configure o Serviço de Aplicativo para usar somente HTTPS. Isso faz com que o Serviço de Aplicativo redirecione de HTTP para HTTPS. Considere fortemente o uso de HTTP Strict Transport Security (HSTS) em seu código ou a partir de seu WAF, que informa aos navegadores que o site só deve ser acessado usando HTTPS.", - "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", - "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", - "service": "App Services", - "severity": "Alto", - "text": "Usar somente HTTPS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Uma SAS pode incluir parâmetros nos quais endereços IP de cliente ou intervalos de endereços estão autorizados a solicitar um recurso usando a SAS. ", + "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", + "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", + "service": "Azure Storage", + "severity": "Média", + "text": "Considere a definição do escopo do SAS para um endereço IP de cliente específico, sempre que possível", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Não use curingas em sua configuração do CORS, pois isso permite que todas as origens acessem o serviço (derrotando assim o propósito do CORS). Especificamente, permita apenas as origens que você espera poder acessar o serviço.", - "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", - "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", - "service": "App Services", - "severity": "Alto", - "text": "Curingas não devem ser usados para CORS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Um SAS não pode restringir a quantidade de dados que um cliente carrega; Dado o modelo de precificação da quantidade de armazenamento ao longo do tempo, pode fazer sentido validar se os clientes carregaram conteúdo maliciosamente grande.", + "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", + "service": "Azure Storage", + "severity": "Baixo", + "text": "Considere verificar os dados carregados, depois que os clientes usaram um SAS para carregar um arquivo. ", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "A depuração remota não deve ser ativada na produção, pois isso abre portas adicionais no serviço, o que aumenta a superfície de ataque. Observe que o serviço ativa a depuração remota automaticamente após 48 horas.", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", - "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", - "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Ao acessar o armazenamento de blob via SFTP usando uma 'conta de usuário local', os controles RBAC 'normais' não se aplicam. O acesso a blobs via NFS ou REST pode ser mais restritivo do que o acesso a SFTP. Infelizmente, no início de 2023, os usuários locais são a única forma de gerenciamento de identidade que atualmente é suportada para o ponto de extremidade SFTP", + "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", + "service": "Azure Storage", "severity": "Alto", - "text": "Desativar a depuração remota", + "text": "SFTP: Limite a quantidade de 'usuários locais' para acesso SFTP e audite se o acesso é necessário ao longo do tempo.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Habilite o Defender para o Serviço de Aplicativo. Isso (entre outras ameaças) detecta comunicações com endereços IP mal-intencionados conhecidos. Analise as recomendações do Defender for App Service como parte de suas operações.", - "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", + "service": "Azure Storage", "severity": "Média", - "text": "Habilitar o Defender for Cloud - Defender for App Service", + "text": "SFTP: O ponto de extremidade SFTP não oferece suporte a ACLs do tipo POSIX.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "O Azure fornece proteção contra DDoS Basic em sua rede, que pode ser aprimorada com recursos inteligentes de DDoS Standard que aprendem sobre padrões normais de tráfego e podem detectar comportamentos incomuns. O DDoS Standard se aplica a uma Rede Virtual, portanto, ele deve ser configurado para o recurso de rede na frente do aplicativo, como o Application Gateway ou um NVA.", - "guid": "223ece80-b123-4071-a541-6415833ea3ad", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "service": "App Services", - "severity": "Média", - "text": "Habilitar o padrão de proteção DDOS na rede virtual WAF", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "O armazenamento oferece suporte a CORS (Cross-Origin Resource Sharing), ou seja, um recurso HTTP que permite que aplicativos Web de um domínio diferente afrouxem a política de mesma origem. Ao habilitar o CORS, mantenha o CorsRules com o menor privilégio.", + "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", + "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", + "service": "Azure Storage", + "severity": "Alto", + "text": "Evite políticas CORS excessivamente amplas", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Ao usar imagens armazenadas no Registro de Contêiner do Azure, extraia-as por uma rede virtual do Registro de Contêiner do Azure usando seu ponto de extremidade privado e a configuração do aplicativo 'WEBSITE_PULL_IMAGE_OVER_VNET'.", - "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", - "service": "App Services", - "severity": "Média", - "text": "Extrair contêineres por uma rede virtual", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Os dados em repouso são sempre criptografados no lado do servidor e, além disso, também podem ser criptografados no lado do cliente. A criptografia do lado do servidor pode acontecer usando uma chave gerenciada por plataforma (padrão) ou uma chave gerenciada pelo cliente. A criptografia do lado do cliente pode acontecer fazendo com que o cliente forneça uma chave de criptografia/descriptografia por blob para o armazenamento do Azure ou manipulando completamente a criptografia no lado do cliente. portanto, não depende do Armazenamento do Azure para garantias de confidencialidade.", + "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", + "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", + "service": "Azure Storage", + "severity": "Alto", + "text": "Determine como os dados em repouso devem ser criptografados. Entenda o modelo de thread para dados.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Realizar um teste de penetração na aplicação web seguindo as regras de teste de penetração de engajamento.", - "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", - "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", + "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", + "service": "Azure Storage", "severity": "Média", - "text": "Realizar um teste de penetração", + "text": "Determine qual/se a criptografia de plataforma deve ser usada.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Implante código confiável que foi validado e verificado em busca de vulnerabilidades de acordo com as práticas de DevSecOps.", - "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", + "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "service": "Azure Storage", "severity": "Média", - "text": "Implantar código validado", + "text": "Determine qual/se a criptografia do lado do cliente deve ser usada.", "waf": "Segurança" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "Use as versões mais recentes de plataformas, linguagens de programação, protocolos e estruturas suportadas.", - "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", - "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", - "service": "App Services", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "Aproveite o Resource Graph Explorer (resources | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true) para localizar contas de armazenamento que permitem acesso anônimo a blobs.", + "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", + "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", + "service": "Azure Storage", "severity": "Alto", - "text": "Use plataformas, linguagens, protocolos e frameworks atualizados", + "text": "Considere se o acesso de blob público é necessário ou se pode ser desabilitado para determinadas contas de armazenamento. ", "waf": "Segurança" }, { @@ -10666,11 +11233,51 @@ "severity": "Alto", "text": "Ao usar o Front Door com origem como serviços de aplicativos, considere bloquear o tráfego para serviços de aplicativos somente por meio do Azure Front Door usando restrições de acesso. ", "waf": "Segurança" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "Alto", + "text": "Habilite a redundância de zona para o Cache do Azure para Redis. O Cache do Azure para Redis dá suporte a configurações com redundância de zona nas camadas Premium e Enterprise. Um cache com redundância de zona pode colocar seus nós em diferentes Zonas de Disponibilidade do Azure na mesma região. Ele elimina a interrupção do data center ou da AZ como um único ponto de falha e aumenta a disponibilidade geral do cache.", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "Média", + "text": "Configure a persistência de dados para uma instância do Cache do Azure para Redis. Como os dados de cache são armazenados na memória, uma falha rara e não planejada de vários nós pode fazer com que todos os dados sejam descartados. Para evitar a perda completa de dados, a persistência do Redis permite que você tire instantâneos periódicos de dados na memória e armazene-os em sua conta de armazenamento.", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "Média", + "text": "Use a conta de armazenamento com redundância geográfica para manter os dados do Cache do Azure para Redis ou com redundância zonal em que a redundância geográfica não está disponível", + "waf": "Fiabilidade" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "Média", + "text": "Configure a replicação geográfica passiva para instâncias do Cache do Azure Premium para Redis. A replicação geográfica é um mecanismo para vincular duas ou mais instâncias do Cache do Azure para Redis, normalmente abrangendo duas regiões do Azure. A replicação geográfica foi projetada principalmente para recuperação de desastres entre regiões. Duas instâncias de cache da camada Premium são conectadas por meio da replicação geográfica de uma forma que fornece leituras e gravações no cache primário e esses dados são replicados para o cache secundário.", + "waf": "Fiabilidade" } ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/checklists/waf_checklist.zh-Hant.json b/checklists/waf_checklist.zh-Hant.json index 6312a16d..92478212 100644 --- a/checklists/waf_checklist.zh-Hant.json +++ b/checklists/waf_checklist.zh-Hant.json @@ -1,1587 +1,1955 @@ { "items": [ { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "ac1d6380-f866-4bbd-a9b4-b1ee5d7908b8", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#availability-zones", - "service": "IoT", - "severity": "高", - "text": "利用可用區(如果區域適用)(這是自動啟用的)", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "35f651e8-0124-4ef7-8c57-658e38609e6e", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", - "service": "IoT", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "應用與存儲相關的 Microsoft 雲安全基準中的指導", + "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", + "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", + "service": "Azure Storage", "severity": "中等", - "text": "請注意 Microsoft 發起的故障轉移。Microsoft 在極少數情況下會執行這些操作,以將所有IoT中心從受影響的區域故障轉移到相應的異地配對區域。", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "4ed3e490-dc06-4a1e-b467-5d0239d85540", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#cross-region-dr", - "service": "IoT", - "severity": "高", - "text": "考慮為關鍵工作負載制定跨區域災難恢復策略", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "a11ecab0-db47-46f7-9aa7-17764e7e45a1", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", - "service": "IoT", - "severity": "高", - "text": "瞭解如何觸發手動故障轉移。", - "waf": "可靠性" + "text": "請考慮「存儲的 Azure 安全基線”", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/IotHubs", - "checklist": "IoT Hub Review", - "guid": "f9db8dfb-1194-460b-aedd-34dd6a69db22", - "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#failback", - "service": "IoT", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "默認情況下,Azure 儲存具有公共IP位址,並且可通過Internet訪問。專用終結點允許僅向需要訪問的 Azure 計算資源安全地公開 Azure 存儲,從而消除對公共 Internet 的暴露", + "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", + "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", + "service": "Azure Storage", "severity": "高", - "text": "瞭解如何在故障轉移後進行故障回復。", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "6d8e32a8-3892-479d-a40b-10f6b4f6f298", - "link": "https://learn.microsoft.com/azure/spring-apps/concepts-blue-green-deployment-strategies", - "service": "Spring Apps", - "severity": "中等", - "text": "Azure Spring Apps 允許對每個應用進行兩次部署,其中只有一個部署接收生產流量。您可以使用藍綠部署策略實現零停機時間。藍綠部署僅在標準層和企業層中可用。可以使用 CI/CD 和 ADO/GitHub 操作自動執行部署", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "fbcb40ac-9480-4a6d-bcf4-8081252a6716", - "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", - "service": "Spring Apps", - "severity": "中等", - "text": "可以在多個區域中為應用程式創建 Azure Spring Apps 實例,並且流量管理器/Front Door 可以路由流量。", - "waf": "可靠性" + "text": "考慮將專用終結點用於 Azure 存儲", + "waf": "安全" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "ff1ae6a7-9301-4feb-9d11-56cd72f1d4ef", - "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", - "service": "Spring Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "新創建的存儲帳戶是使用ARM部署模型創建的,因此 RBAC、審核等都已啟用。確保訂閱中沒有具有經典部署模型的舊存儲帳戶", + "guid": "30e37c3e-2971-41b2-963c-eee079b598de", + "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", + "service": "Azure Storage", "severity": "中等", - "text": "在支持的區域中,Azure Spring Apps 可以部署為區域冗餘,這意味著實例會自動分佈在可用性區域之間。此功能僅在標準層和企業層中可用。", - "waf": "可靠性" + "text": "確保較舊的存儲帳戶未使用“經典部署模型”", + "waf": "安全" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "ffc735ad-fbb1-4802-b43f-ad6387c4c066", - "link": "https://learn.microsoft.com/azure/spring-apps/concept-understand-app-and-deployment", - "service": "Spring Apps", - "severity": "中等", - "text": "對應用使用1個以上的應用實例", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "利用 Microsoft Defender 瞭解可疑活動和錯誤配置。", + "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", + "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", + "service": "Azure Storage", + "severity": "高", + "text": "為所有存儲帳戶啟用 Microsoft DefenderEnable Defender for all of your storage accounts", + "waf": "安全" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "7504c230-6035-4183-95a5-85762acc6075", - "link": "https://learn.microsoft.com/azure/spring-apps/diagnostic-services", - "service": "Spring Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "軟刪除機制允許恢復意外刪除的 Blob。", + "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", + "service": "Azure Storage", "severity": "中等", - "text": "使用日誌、指標和跟蹤監視 Azure Spring Apps。將 ASA 與應用程式見解集成,並跟蹤故障並創建工作簿。", - "waf": "可靠性" + "text": "為 blob 啟用“軟刪除”", + "waf": "安全" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "1eb48d58-3eec-4ef5-80b0-d2b0dde3f0c6", - "link": "https://learn.microsoft.com/azure/spring-apps/how-to-configure-enterprise-spring-cloud-gateway", - "service": "Spring Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "請考慮有選擇地禁用某些 blob 容器的「軟刪除」 例如,如果應用程式必須確保立即刪除已刪除的資訊,例如出於機密性、隱私或合規性原因。", + "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", + "service": "Azure Storage", "severity": "中等", - "text": "在 Spring Cloud Gateway 中設置自動縮放", - "waf": "可靠性" + "text": "禁用 blob 的“軟刪除”", + "waf": "安全" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "97411607-b6fd-4335-99d1-9885faf4e392", - "link": "https://learn.microsoft.com/azure/spring-apps/how-to-setup-autoscale", - "service": "Spring Apps", - "severity": "低", - "text": "為具有標準使用量和專用計劃的應用啟用自動縮放。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "容器的軟刪除使你能夠在刪除容器后恢復容器,例如從意外刪除操作中恢復。", + "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", + "service": "Azure Storage", + "severity": "高", + "text": "為容器啟用“軟刪除”", + "waf": "安全" }, { - "arm-service": "Microsoft.AppPlatform/Spring", - "checklist": "Azure Spring Apps Review", - "guid": "dfcaffd1-d27c-4ef2-998d-64c1df3a7ac3", - "link": "https://learn.microsoft.com/azure/spring-apps/overview", - "service": "Spring Apps", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "請考慮有選擇地禁用某些 blob 容器的「軟刪除」 例如,如果應用程式必須確保立即刪除已刪除的資訊,例如出於機密性、隱私或合規性原因。", + "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", + "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", + "service": "Azure Storage", "severity": "中等", - "text": "使用企業計劃為關鍵任務應用提供 Spring Boot 的商業支援。使用其他層,您可以獲得 OSS 支援。", - "waf": "可靠性" + "text": "禁用容器的“軟刪除”", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "cb26b2ba-a9db-45d1-8260-d9c6ec1447d9", - "link": "https://learn.microsoft.com/en-us/azure/logic-apps/single-tenant-overview-compare", - "service": "IoT Hub DPS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "通過強制使用者在刪除之前先刪除刪除鎖,防止意外刪除存儲帳戶", + "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", + "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", + "service": "Azure Storage", "severity": "高", - "text": "根據業務和 SLO 要求選擇正確的邏輯應用託管計劃", - "waf": "可靠性" + "text": "在存儲帳戶上啟用資源鎖", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "f6dd7977-1123-4f39-b488-f91415a8430a", - "link": "https://learn.microsoft.com/en-us/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", - "service": "IoT Hub DPS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "請考慮對 blob 使用“合法保留”或“基于時間的保留”策略,這樣就無法刪除 blob、容器或存儲帳戶。請注意,「不可能」實際上意味著「不可能」;存儲帳戶包含不可變 blob 後,「擺脫」該存儲帳戶的唯一方法是取消 Azure 訂閱。", + "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", + "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", + "service": "Azure Storage", "severity": "高", - "text": "使用區域冗餘和可用性區域保護邏輯應用免受區域故障的影響", - "waf": "可靠性" + "text": "考慮不可變的 blob", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "8aed4fbf-0830-4883-899d-222a154af478", - "link": "https://learn.microsoft.com/en-us/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", - "service": "IoT Hub DPS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "請考慮禁用對存儲帳戶的未受保護的 HTTP/80 訪問,以便對所有數據傳輸進行加密、完整性保護,並對伺服器進行身份驗證。", + "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", + "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", + "service": "Azure Storage", "severity": "高", - "text": "考慮為關鍵工作負載制定跨區域災難恢復策略", - "waf": "可靠性" + "text": "需要 HTTPS,即在儲存帳戶上禁用埠 80", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "da0f033e-d180-4f36-9aa4-c468dba14203", - "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", - "service": "IoT Hub DPS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "在儲存帳戶上配置自定義域(主機名)時,請檢查是否需要 TLS/HTTPS;如果是這樣,可能需要將 Azure CDN 放在存儲帳戶的前面。", + "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", + "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", + "service": "Azure Storage", "severity": "高", - "text": "如果部署到獨立環境,請使用或遷移到應用服務環境 (ASE) v3", - "waf": "可靠性" + "text": "強制實施 HTTPS(禁用 HTTP)時,請檢查是否未對儲存帳戶使用自定義域 (CNAME)。", + "waf": "安全" }, { - "arm-service": "Microsoft.Devices/provisioningServices", - "checklist": "Device Provisioning Service Review", - "guid": "62711604-c9d1-4b0a-bdb7-5fda54a4f6c1", - "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", - "service": "IoT Hub DPS", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "當用戶端使用SAS令牌訪問 blob 資料時,要求使用 HTTPS 有助於將憑據丟失的風險降至最低。", + "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", + "service": "Azure Storage", "severity": "中等", - "text": "利用 Azure DevOps 或 GitHub 簡化 CI/CD 並保護邏輯應用代碼", - "waf": "操作" + "text": "將共享訪問簽名 (SAS) 令牌限製為僅 HTTPS 連接", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "6d37a33b-531c-4a91-871a-b69d8044f04e", - "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", - "service": "Key Vault", - "severity": "高", - "text": "熟悉 Key Vault 的最佳實踐,例如隔離建議、訪問控制、數據保護、備份和日誌記錄。", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "7ba4d380-7b9e-4a8b-a0c3-2d8e49c11872", - "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", - "service": "Key Vault", - "severity": "中等", - "text": "Key Vault 是一項託管服務,Microsoft 將處理區域內和區域之間的故障轉移。熟悉 Key Vault 的可用性和冗餘。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "在可能的情況下,AAD 令牌應優先於共用訪問簽名", + "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", + "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", + "service": "Azure Storage", + "severity": "高", + "text": "使用 Azure Active Directory (Azure AD) 令牌進行 blob 訪問", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "17fb86a2-eb45-42a4-9c34-52b92a2a1842", - "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance#data-replication", - "service": "Key Vault", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "將角色分配給使用者、組或應用程式時,請僅向該安全主體授予他們執行任務所需的許可權。限制對資源的訪問有助於防止無意和惡意濫用數據。", + "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", + "service": "Azure Storage", "severity": "中等", - "text": "密鑰保管庫的內容將在區域內複製到至少 150 英里外的次要區域,但要在同一地理位置內,以保持金鑰和機密的高持久性。熟悉 Key Vault 的數據複製。", - "waf": "可靠性" + "text": "IaM 許可權中的最低特權", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "614682ca-6e0c-4f34-9f03-c6d3f2b99a32", - "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance#failover-across-regions", - "service": "Key Vault", - "severity": "中等", - "text": "在故障轉移期間,無法訪問策略或防火牆配置和設置。在故障轉移期間,金鑰保管庫將處於只讀模式。熟悉 Key Vault 的故障轉移指南。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "使用者委派 SAS 使用 Azure Active Directory (Azure AD) 憑據以及為 SAS 指定的許可權進行保護。使用者委派 SAS 在範圍和功能方面類似於服務 SAS,但比服務 SAS 具有安全優勢。", + "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", + "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", + "service": "Azure Storage", + "severity": "高", + "text": "使用 SAS 時,首選「使用者委派 SAS」,而不是基於存儲帳戶密鑰的 SAS。", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "9ef2b0d2-3206-4c94-b47a-4f07e6a1c509", - "link": "https://learn.microsoft.com/azure/key-vault/general/backup?tabs=azure-cli#design-considerations", - "service": "Key Vault", - "severity": "中等", - "text": "備份金鑰保管庫物件(例如機密、金鑰或證書)時,備份操作會將該物件下載為加密的 blob。無法在 Azure 外部解密此 blob。若要從此 blob 獲取可用數據,必須將 blob 還原到同一 Azure 訂閱和 Azure 地理位置中的金鑰保管庫中。熟悉 Key Vault 的備份和還原指南。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "存儲帳戶金鑰(“共用金鑰”)幾乎沒有審核功能。雖然可以監控誰/何時獲取密鑰副本,但一旦密鑰掌握在多個人手中,就不可能將使用方式歸因於特定使用者。僅依靠 AAD 身份驗證可以更輕鬆地將存儲存取許可權綁定到使用者。", + "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", + "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", + "service": "Azure Storage", + "severity": "高", + "text": "請考慮禁用存儲帳戶密鑰,以便僅支援 AAD 訪問(和使用者委派 SAS)。", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "2df045b1-c0f6-47d3-9a9b-99cf6999684e", - "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview", - "service": "Key Vault", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "使用活動日誌數據來標識查看或更改存儲帳戶安全性的“時間”、“人員”、“內容”和“方式”(即存儲帳戶密鑰、訪問策略等)。", + "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", + "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", + "service": "Azure Storage", "severity": "高", - "text": "如果要防止意外或惡意刪除機密,請在密鑰保管庫上配置軟刪除和清除保護功能。", - "waf": "可靠性" + "text": "請考慮使用 Azure Monitor 審核存儲帳戶上的控制平面操作", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "cbfa96b0-5249-4e6f-947c-d0e79509708c", - "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview", - "service": "Key Vault", - "severity": "低", - "text": "Key Vault 的軟刪除資源將保留 90 個日曆日的固定期限。熟悉 Key Vault 的軟刪除指南。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "通過金鑰過期策略,您可以設置帳戶訪問金鑰輪換的提醒。如果指定的時間間隔已過且鍵尚未旋轉,則會顯示提醒。", + "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", + "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", + "service": "Azure Storage", + "severity": "中等", + "text": "使用存儲帳戶密鑰時,請考慮啟用“金鑰過期策略”", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "e8659d11-7e02-4db0-848c-c6541dbab68c", - "link": "https://learn.microsoft.com/azure/key-vault/general/backup?tabs=azure-cli#limitations", - "service": "Key Vault", - "severity": "低", - "text": "瞭解 Key Vault 的備份限制。Key Vault 不支援備份超過 500 個金鑰、機密或證書對象的過去版本。嘗試備份金鑰、金鑰或證書物件可能會導致錯誤。無法刪除金鑰、金鑰或證書的早期版本。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS 過期策略指定 SAS 有效的建議時間間隔。SAS 過期策略適用於服務 SAS 或帳戶 SAS。當使用者生成的服務 SAS 或帳戶 SAS 的有效期間隔大於建議的時間間隔時,他們會看到警告。", + "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", + "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", + "service": "Azure Storage", + "severity": "中等", + "text": "考慮配置 SAS 過期策略", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "45c25e29-d0ef-4f07-aa04-0f8c64cbcc04", - "link": "https://learn.microsoft.com/azure/key-vault/general/backup?tabs=azure-cli#limitations", - "service": "Key Vault", - "severity": "低", - "text": "Key Vault 目前不提供在單個操作中備份整個 Key Vault 的方法,並且必須單獨備份密鑰、機密和證書。熟悉 Key Vault 的備份和還原指南。", - "waf": "可靠性" + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "存儲存取策略提供了撤銷服務 SAS 許可權的選項,而無需重新生成儲存帳戶密鑰。", + "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", + "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", + "service": "Azure Storage", + "severity": "中等", + "text": "考慮將 SAS 連結到儲存存取策略", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "guid": "0f15640b-31e5-4de6-85a7-d2c652fa09d3", - "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview#purge-protection", - "service": "Key Vault", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", + "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", + "service": "Azure Storage", "severity": "中等", - "text": "使用金鑰進行加密時,建議使用清除保護,以防止數據丟失。清除保護是一種可選的 Key Vault 行為,預設情況下未啟用。只有在啟用軟刪除後,才能啟用清除保護。可以通過 CLI、PowerShell 或 Portal 打開它。", - "waf": "可靠性" + "text": "請考慮配置應用程式的原始程式碼儲存庫,以檢測簽入的連接字串和存儲帳戶密鑰。", + "waf": "安全" }, { - "arm-service": "Microsoft.KeyVault/vaults", - "checklist": "Azure Key Vault", - "graph": "resources| where type =~ 'microsoft.keyvault/vaults' | extend compliant = (properties.enableRbacAuthorization == true) | distinct id, compliant", - "guid": "d0642c1c-312b-4116-94ab-439e1c836819", - "link": "https://learn.microsoft.com/azure/key-vault/general/rbac-guide?tabs=azure-cli", - "service": "Key Vault", - "severity": "中等", - "text": "建議使用 RBAC 來控制對 Key Vault 的訪問。熟悉 Key Vault 的訪問控制指南。", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "理想情況下,應用程式應使用託管標識向 Azure 儲存進行身份驗證。如果無法做到這一點,請考慮在 Azure KeyVault 或等效服務中使用存儲憑據(連接字串、存儲帳戶密鑰、SAS、服務主體憑據)。", + "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", + "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", + "service": "Azure Storage", + "severity": "高", + "text": "請考慮將連接字串儲存在 Azure KeyVault 中(在無法實現託管標識的情況下)", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Azure 服務總線高級版提供靜態數據加密。如果您使用自己的金鑰,則數據仍使用 Microsoft 管理的金鑰進行加密,但此外,Microsoft 管理的金鑰將使用客戶管理的密鑰進行加密。", - "guid": "87af4a79-1f89-439b-ba47-768e14c11567", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/configure-customer-managed-key", - "service": "Service Bus", - "severity": "低", - "text": "需要時,在靜態數據加密中使用客戶管理的金鑰選項", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "在臨時 SAS 服務 SAS 或帳戶 SAS 上使用近期過期時間。這樣,即使 SAS 遭到入侵,它也只能在很短的時間內有效。如果無法引用存儲訪問策略,則此做法尤為重要。近期過期時間還通過限制可上傳到 blob 的時間來限制可寫入 blob 的數據量。", + "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", + "severity": "高", + "text": "爭取縮短臨時 SAS 的有效期", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "用戶端應用程式與 Azure 服務總線命名空間之間的通信使用傳輸層安全性 (TLS) 進行加密。Azure 服務總線命名空間允許用戶端使用 TLS 1.0 及更高版本發送和接收數據。若要強制實施更嚴格的安全措施,可以將服務總線命名空間配置為要求用戶端使用較新版本的 TLS 發送和接收數據。", - "guid": "5c1ea55b-46a9-448f-b8ae-7d7e4b475b6c", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/transport-layer-security-enforce-minimum-version", - "service": "Service Bus", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "創建 SAS 時,請盡可能具體和嚴格。首選單個資源和操作的 SAS,而不是提供更廣泛訪問許可權的 SAS。", + "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", + "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", + "service": "Azure Storage", "severity": "中等", - "text": "對請求強制實施最低要求的傳輸層安全性 (TLS) 版本", - "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", + "text": "將窄範圍應用於SAS", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "創建服務總線命名空間時,會自動為命名空間創建名為 RootManageSharedAccessKey 的 SAS 規則。此策略具有整個命名空間的 Manage 許可權。建議您將此規則視為管理根帳戶,不要在應用程式中使用它。 建議使用 AAD 作為 RBAC 的身份驗證提供程式。", - "guid": "8bcbf59b-ce65-4de8-a03f-97879468d66a", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", - "service": "Service Bus", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS 可以包含用戶端 IP 位址或位址範圍有權使用 SAS 請求資源的參數。", + "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", + "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", + "service": "Azure Storage", "severity": "中等", - "text": "避免在不需要時使用 root 帳戶", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", + "text": "盡可能考慮將SAS的範圍限定為特定的用戶端IP位址", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "在 Azure 應用服務應用程式內或在啟用了 Azure 資源支援的託管實體的虛擬機中運行的服務總線用戶端應用不需要處理 SAS 規則和密鑰或任何其他存取權杖。用戶端應用程式只需要 Service Bus Messaging 命名空間的終結點位址。", - "guid": "786d60f9-6c96-4ad8-a55d-04c2b39c986b", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-managed-service-identity", - "service": "Service Bus", - "severity": "中等", - "text": "如果可能,應用程式應使用託管標識向 Azure 服務總線進行身份驗證。如果沒有,請考慮在 Azure Key Vault 或等效服務中使用存儲憑據(SAS、服務主體憑據)", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "SAS 無法限制用戶端上傳的數據量;考慮到存儲量隨時間變化的定價模型,驗證用戶端是否惡意上傳了大量內容可能是有意義的。", + "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", + "service": "Azure Storage", + "severity": "低", + "text": "請考慮在用戶端使用SAS上傳檔后檢查上傳的數據。", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "創建許可權時,請對用戶端對 Azure 服務總線的訪問提供精細控制。Azure 服務總線中的許可權可以而且應該限定為單個資源級別,例如佇列、主題或訂閱。", - "guid": "f615658d-e558-4f93-9249-b831112dbd7e", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", - "service": "Service Bus", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "使用「本地使用者帳戶」通過 SFTP 訪問 Blob 儲存時,“通常”RBAC 控制不適用。通過 NFS 或 REST 進行的 Blob 訪問可能比 SFTP 訪問更嚴格。遺憾的是,截至 2023 年初,本地使用者是 SFTP 端點當前支援的唯一身份管理形式", + "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", + "service": "Azure Storage", "severity": "高", - "text": "使用最低許可權數據平面 RBAC", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "text": "SFTP:限制 SFTP 訪問的「本地使用者」數量,並審核一段時間內是否需要訪問。", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "Azure 服務總線資源日誌包括操作日誌、虛擬網路和IP篩選日誌。運行時審核日誌捕獲服務總線中各種數據平面訪問操作(例如發送或接收消息)的聚合診斷資訊。", - "guid": "af12e7f9-43f6-4304-922d-929c2b1cd622", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", - "service": "Service Bus", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", + "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", + "service": "Azure Storage", "severity": "中等", - "text": "啟用記錄以進行安全調查。使用 Azure Monitor 追蹤資源紀錄和執行時審核紀錄(目前僅在進階層中可用 )", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", + "text": "SFTP:SFTP 端點不支持類似 POSIX 的 ACL。", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "默認情況下,Azure 服務總線具有公共IP位址,並且可通過Internet訪問。專用終結點允許虛擬網路與 Azure 服務總線之間的流量遍歷 Microsoft 主幹網路。除此之外,如果未使用公有終端節點,則應禁用這些終端節點。", - "guid": "9ae669ca-48e4-4a85-b222-3ece8bb12307", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", - "service": "Service Bus", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "存儲支援 CORS(跨域資源分享),即一種 HTTP 功能,使來自不同域的 Web 應用程式能夠放寬同源策略。啟用 CORS 時,請將 CorsRules 保留為最低許可權。", + "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", + "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", + "service": "Azure Storage", + "severity": "高", + "text": "避免過於寬泛的 CORS 策略", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "靜態數據始終在伺服器端加密,此外也可能在用戶端加密。伺服器端加密可能使用平臺管理的金鑰(預設)或客戶管理的金鑰進行。用戶端加密可以通過讓用戶端按 blob 向 Azure 儲存提供加密/解密金鑰,或者完全在用戶端處理加密來實現。因此,完全不依賴 Azure 存儲來保證機密性。", + "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", + "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", + "service": "Azure Storage", + "severity": "高", + "text": "確定應如何加密靜態數據。了解數據的線程模型。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", + "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", + "service": "Azure Storage", "severity": "中等", - "text": "請考慮使用專用終結點訪問 Azure 服務總線,並在適用時禁用公用網路訪問。", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "text": "確定應使用哪種/是否應使用平臺加密。", "waf": "安全" }, { - "arm-service": "Microsoft.ServiceBus/namespaces", - "checklist": "Service Bus Review Checklist", - "description": "使用IP防火牆,您可以將公有終端節點進一步限製為僅一組 IPv4 位址或 CIDR(無類域間路由)表示法的 IPv4 位址範圍。", - "guid": "ca5f06f1-58e3-4ea3-a92c-2de7e2165c3a", - "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-ip-filtering", - "service": "Service Bus", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", + "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", + "service": "Azure Storage", "severity": "中等", - "text": "請考慮僅允許從特定IP位址或範圍訪問 Azure 服務總線命名空間", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "text": "確定應使用哪種/是否應使用用戶端加密。", "waf": "安全" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "b32e1aa1-4813-4602-88fe-27ca2891f421", - "link": "https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/app-service-web-app/zone-redundant?source=recommendations", - "service": "App Services", - "severity": "低", - "text": "有關最佳實踐,請參閱基線高可用性區域冗餘 Web 應用程式體系結構", + "arm-service": "Microsoft.Storage/storageAccounts", + "checklist": "Azure Blob Storage Review", + "description": "利用 Resource Graph 資源管理器(資源 | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true)查找允許匿名 blob 訪問的存儲帳戶。", + "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", + "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", + "service": "Azure Storage", + "severity": "高", + "text": "考慮是否需要公共 blob 訪問,或者是否可以對某些存儲帳戶禁用公共 blob 訪問。", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "ac1d6380-f866-4bbd-a9b4-b1ee5d7908b8", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#availability-zones", + "service": "IoT", + "severity": "高", + "text": "利用可用區(如果區域適用)(這是自動啟用的)", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "e4b31c6a-2e3f-4df1-8e8b-9c3aa5a27820", - "link": "https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans", - "service": "App Services", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "35f651e8-0124-4ef7-8c57-658e38609e6e", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", + "service": "IoT", "severity": "中等", - "text": "使用高級層和標準層。這些層支援暫存槽和自動備份。", + "text": "請注意 Microsoft 發起的故障轉移。Microsoft 在極少數情況下會執行這些操作,以將所有IoT中心從受影響的區域故障轉移到相應的異地配對區域。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "a7e2e6c2-491f-4fa4-a82b-521d0bc3b202", - "link": "https://learn.microsoft.com/en-us/azure/reliability/migrate-app-service", - "service": "App Services", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "4ed3e490-dc06-4a1e-b467-5d0239d85540", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#cross-region-dr", + "service": "IoT", "severity": "高", - "text": "利用區域適用的可用性區域(需要高級 v2 或 v3 層)", + "text": "考慮為關鍵工作負載制定跨區域災難恢復策略", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "1275e4a9-7b6a-43c3-a9cd-5ee18d8995ad", - "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", - "service": "App Services", - "severity": "中等", - "text": "實施健康檢查", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "a11ecab0-db47-46f7-9aa7-17764e7e45a1", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#microsoft-initiated-failover", + "service": "IoT", + "severity": "高", + "text": "瞭解如何觸發手動故障轉移。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "35a91c5d-4ad6-4d9b-8e0f-c47db9e6d1e7", - "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-backup", - "service": "App Services", + "arm-service": "Microsoft.Devices/IotHubs", + "checklist": "IoT Hub Review", + "guid": "f9db8dfb-1194-460b-aedd-34dd6a69db22", + "link": "https://learn.microsoft.com/azure/iot-hub/iot-hub-ha-dr#failback", + "service": "IoT", "severity": "高", - "text": "請參閱 Azure 應用服務的備份和還原最佳做法", + "text": "瞭解如何在故障轉移後進行故障回復。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "e68cd0ec-afc6-4bd8-a27f-7860ad9a0db2", - "link": "https://learn.microsoft.com/en-us/azure/architecture/framework/services/compute/azure-app-service/reliability", - "service": "App Services", - "severity": "高", - "text": "實現 Azure 應用服務可靠性最佳做法", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "6d8e32a8-3892-479d-a40b-10f6b4f6f298", + "link": "https://learn.microsoft.com/azure/spring-apps/concepts-blue-green-deployment-strategies", + "service": "Spring Apps", + "severity": "中等", + "text": "Azure Spring Apps 允許對每個應用進行兩次部署,其中只有一個部署接收生產流量。您可以使用藍綠部署策略實現零停機時間。藍綠部署僅在標準層和企業層中可用。可以使用 CI/CD 和 ADO/GitHub 操作自動執行部署", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "bd2a865c-0835-4418-bb58-4df91a5a9b3f", - "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-disaster-recovery#recover-app-content-only", - "service": "App Services", - "severity": "低", - "text": "熟悉如何在災難期間將應用服務應用移動到另一個區域", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "fbcb40ac-9480-4a6d-bcf4-8081252a6716", + "link": "https://learn.microsoft.com/azure/architecture/web-apps/spring-apps/architectures/spring-apps-multi-region", + "service": "Spring Apps", + "severity": "中等", + "text": "可以在多個區域中為應用程式創建 Azure Spring Apps 實例,並且流量管理器/Front Door 可以路由流量。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "f3d2f1e4-e6d4-4b7a-a5a5-e2a9b2c6f293", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-app-service", - "service": "App Services", - "severity": "高", - "text": "熟悉 Azure 應用服務中的可靠性支援", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "ff1ae6a7-9301-4feb-9d11-56cd72f1d4ef", + "link": "https://learn.microsoft.com/azure/reliability/reliability-spring-apps", + "service": "Spring Apps", + "severity": "中等", + "text": "在支持的區域中,Azure Spring Apps 可以部署為區域冗餘,這意味著實例會自動分佈在可用性區域之間。此功能僅在標準層和企業層中可用。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "c7b5f3d1-0569-4fd2-9f32-c0b64e9c0c5e", - "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", - "service": "App Services", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "ffc735ad-fbb1-4802-b43f-ad6387c4c066", + "link": "https://learn.microsoft.com/azure/spring-apps/concept-understand-app-and-deployment", + "service": "Spring Apps", "severity": "中等", - "text": "確保為在應用服務計劃上運行的函數應用啟用“Always On”", + "text": "對應用使用1個以上的應用實例", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "a3b4d5f6-758c-4f9d-9e1a-d7c6b7e8f9ab", - "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", - "service": "App Services", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "7504c230-6035-4183-95a5-85762acc6075", + "link": "https://learn.microsoft.com/azure/spring-apps/diagnostic-services", + "service": "Spring Apps", "severity": "中等", - "text": "使用運行狀況檢查監視應用服務實例", + "text": "使用日誌、指標和跟蹤監視 Azure Spring Apps。將 ASA 與應用程式見解集成,並跟蹤故障並創建工作簿。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "c7d3e5f9-a19c-4833-8ca6-1dcb0128e129", - "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-overview", - "service": "App Services", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "1eb48d58-3eec-4ef5-80b0-d2b0dde3f0c6", + "link": "https://learn.microsoft.com/azure/spring-apps/how-to-configure-enterprise-spring-cloud-gateway", + "service": "Spring Apps", "severity": "中等", - "text": "使用 Application Insights 可用性測試監視 Web 應用或網站的可用性和回應能力", + "text": "在 Spring Cloud Gateway 中設置自動縮放", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "guid": "b4e3f2d5-a5c6-4d7e-8b2f-c5d9e7a8f0ea", - "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-standard-tests", - "service": "App Services", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "97411607-b6fd-4335-99d1-9885faf4e392", + "link": "https://learn.microsoft.com/azure/spring-apps/how-to-setup-autoscale", + "service": "Spring Apps", "severity": "低", - "text": "使用 Application Insights 標準測試監視 Web 應用或網站的可用性和回應能力", + "text": "為具有標準使用量和專用計劃的應用啟用自動縮放。", "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "使用 Azure Key Vault 儲存應用程式所需的任何機密。 Key Vault 為儲存機密提供安全且經過審核的環境,並通過 Key Vault SDK 或應用服務 Key Vault 引用與應用服務很好地集成。", - "guid": "834ac932-223e-4ce8-8b12-3071a5416415", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", - "service": "App Services", + "arm-service": "Microsoft.AppPlatform/Spring", + "checklist": "Azure Spring Apps Review", + "guid": "dfcaffd1-d27c-4ef2-998d-64c1df3a7ac3", + "link": "https://learn.microsoft.com/azure/spring-apps/overview", + "service": "Spring Apps", + "severity": "中等", + "text": "使用企業計劃為關鍵任務應用提供 Spring Boot 的商業支援。使用其他層,您可以獲得 OSS 支援。", + "waf": "可靠性" + }, + { + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "cb26b2ba-a9db-45d1-8260-d9c6ec1447d9", + "link": "https://learn.microsoft.com/en-us/azure/logic-apps/single-tenant-overview-compare", + "service": "IoT Hub DPS", "severity": "高", - "text": "使用 Key Vault 儲存機密", - "waf": "安全" + "text": "根據業務和 SLO 要求選擇正確的邏輯應用託管計劃", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "使用託管標識通過 Key Vault SDK 或透過應用服務 Key Vault 引用連接到 Key Vault。", - "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", - "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", - "service": "App Services", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "f6dd7977-1123-4f39-b488-f91415a8430a", + "link": "https://learn.microsoft.com/en-us/azure/logic-apps/set-up-zone-redundancy-availability-zones?tabs=standard#next-steps", + "service": "IoT Hub DPS", "severity": "高", - "text": "使用託管標識連接到 Key VaultUse Managed Identity to connect to Key Vault", - "waf": "安全" + "text": "使用區域冗餘和可用性區域保護邏輯應用免受區域故障的影響", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "將應用服務 TLS 證書存儲在 Key Vault 中。", - "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", - "service": "App Services", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "8aed4fbf-0830-4883-899d-222a154af478", + "link": "https://learn.microsoft.com/en-us/azure/logic-apps/business-continuity-disaster-recovery-guidance?toc=%2Fazure%2Freliability%2Ftoc.json&bc=%2Fazure%2Freliability%2Fbreadcrumb%2Ftoc.json", + "service": "IoT Hub DPS", "severity": "高", - "text": "使用 Key Vault 儲存 TLS 證書。", - "waf": "安全" + "text": "考慮為關鍵工作負載制定跨區域災難恢復策略", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "處理敏感信息的系統應隔離。 為此,請使用單獨的應用服務計劃或應用服務環境,並考慮使用不同的訂閱或管理組。", - "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", - "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", - "service": "App Services", + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "da0f033e-d180-4f36-9aa4-c468dba14203", + "link": "https://learn.microsoft.com/en-us/azure/app-service/environment/intro", + "service": "IoT Hub DPS", + "severity": "高", + "text": "如果部署到獨立環境,請使用或遷移到應用服務環境 (ASE) v3", + "waf": "可靠性" + }, + { + "arm-service": "Microsoft.Devices/provisioningServices", + "checklist": "Device Provisioning Service Review", + "guid": "62711604-c9d1-4b0a-bdb7-5fda54a4f6c1", + "link": "https://learn.microsoft.com/en-us/training/modules/deploy-azure-functions/", + "service": "IoT Hub DPS", "severity": "中等", - "text": "隔離處理敏感信息的系統", - "waf": "安全" + "text": "利用 Azure DevOps 或 GitHub 簡化 CI/CD 並保護邏輯應用代碼", + "waf": "操作" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "應用服務上的本地磁碟未加密,敏感數據不應存儲在這些磁碟上。 (例如:D:\\\\Local 和 %TMP%)。", - "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", - "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", - "service": "App Services", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "6d37a33b-531c-4a91-871a-b69d8044f04e", + "link": "https://learn.microsoft.com/azure/key-vault/general/best-practices", + "service": "Key Vault", + "severity": "高", + "text": "熟悉 Key Vault 的最佳實踐,例如隔離建議、訪問控制、數據保護、備份和日誌記錄。", + "waf": "可靠性" + }, + { + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "7ba4d380-7b9e-4a8b-a0c3-2d8e49c11872", + "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance", + "service": "Key Vault", "severity": "中等", - "text": "不要將敏感數據存儲在本地磁碟上", - "waf": "安全" + "text": "Key Vault 是一項託管服務,Microsoft 將處理區域內和區域之間的故障轉移。熟悉 Key Vault 的可用性和冗餘。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "對於經過身份驗證的 Web 應用程式,請使用成熟的標識提供者,例如 Azure AD 或 Azure AD B2C。 利用所選的應用程式框架與此提供程式整合,或使用應用服務身份驗證/授權功能。", - "guid": "919ca0b2-c121-459e-814b-933df574eccc", - "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", - "service": "App Services", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "17fb86a2-eb45-42a4-9c34-52b92a2a1842", + "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance#data-replication", + "service": "Key Vault", "severity": "中等", - "text": "使用已建立的身份提供程式進行身份驗證", - "waf": "安全" + "text": "密鑰保管庫的內容將在區域內複製到至少 150 英里外的次要區域,但要在同一地理位置內,以保持金鑰和機密的高持久性。熟悉 Key Vault 的數據複製。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "將代碼從受控且受信任的環境(例如管理良好且安全的 DevOps 部署管道)部署到應用服務。這樣可以避免未經版本控制和驗證從惡意主機部署的代碼。", - "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", - "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", - "service": "App Services", - "severity": "高", - "text": "從受信任的環境部署", - "waf": "安全" + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "614682ca-6e0c-4f34-9f03-c6d3f2b99a32", + "link": "https://learn.microsoft.com/azure/key-vault/general/disaster-recovery-guidance#failover-across-regions", + "service": "Key Vault", + "severity": "中等", + "text": "在故障轉移期間,無法訪問策略或防火牆配置和設置。在故障轉移期間,金鑰保管庫將處於只讀模式。熟悉 Key Vault 的故障轉移指南。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "禁用 FTP/FTPS 和 WebDeploy/SCM 的基本身份驗證。 這將禁止訪問這些服務,並強制使用 Azure AD 安全終結點進行部署。 請注意,還可以使用 Azure AD 憑據打開 SCM 網站。", - "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", - "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", - "service": "App Services", - "severity": "高", - "text": "禁用基本身份驗證", - "waf": "安全" + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "9ef2b0d2-3206-4c94-b47a-4f07e6a1c509", + "link": "https://learn.microsoft.com/azure/key-vault/general/backup?tabs=azure-cli#design-considerations", + "service": "Key Vault", + "severity": "中等", + "text": "備份金鑰保管庫物件(例如機密、金鑰或證書)時,備份操作會將該物件下載為加密的 blob。無法在 Azure 外部解密此 blob。若要從此 blob 獲取可用數據,必須將 blob 還原到同一 Azure 訂閱和 Azure 地理位置中的金鑰保管庫中。熟悉 Key Vault 的備份和還原指南。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "如果可能,請使用託管標識連接到 Azure AD 受保護的資源。 如果無法做到這一點,請將機密存儲在 Key Vault 中,並改用託管標識連接到 Key Vault。", - "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", - "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", - "service": "App Services", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "2df045b1-c0f6-47d3-9a9b-99cf6999684e", + "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview", + "service": "Key Vault", "severity": "高", - "text": "使用託管標識連接到資源", - "waf": "安全" + "text": "如果要防止意外或惡意刪除機密,請在密鑰保管庫上配置軟刪除和清除保護功能。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "如果使用 Azure 容器註冊表中儲存的映像,請使用託管標識拉取這些映像。", - "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", - "service": "App Services", - "severity": "高", - "text": "使用託管標識拉取容器", - "waf": "安全" + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "cbfa96b0-5249-4e6f-947c-d0e79509708c", + "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview", + "service": "Key Vault", + "severity": "低", + "text": "Key Vault 的軟刪除資源將保留 90 個日曆日的固定期限。熟悉 Key Vault 的軟刪除指南。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "通過配置應用服務的診斷設置,可以將所有遙測數據發送到Log Analytics,作為日誌記錄和監視的中心目標。這允許你監視應用服務的運行時活動,例如 HTTP 日誌、應用程式日誌、平臺日誌等。", - "guid": "47768314-c115-4775-a2ea-55b46ad48408", - "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", - "service": "App Services", - "severity": "中等", - "text": "將應用服務運行時日誌發送到Log Analytics", - "waf": "安全" + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "e8659d11-7e02-4db0-848c-c6541dbab68c", + "link": "https://learn.microsoft.com/azure/key-vault/general/backup?tabs=azure-cli#limitations", + "service": "Key Vault", + "severity": "低", + "text": "瞭解 Key Vault 的備份限制。Key Vault 不支援備份超過 500 個金鑰、機密或證書對象的過去版本。嘗試備份金鑰、金鑰或證書物件可能會導致錯誤。無法刪除金鑰、金鑰或證書的早期版本。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "設置診斷設置,將活動日誌發送到Log Analytics,作為日誌記錄和監視的中心目標。這樣,你就可以監視應用服務資源本身上的控制平面活動。", - "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", - "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", - "service": "App Services", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "45c25e29-d0ef-4f07-aa04-0f8c64cbcc04", + "link": "https://learn.microsoft.com/azure/key-vault/general/backup?tabs=azure-cli#limitations", + "service": "Key Vault", + "severity": "低", + "text": "Key Vault 目前不提供在單個操作中備份整個 Key Vault 的方法,並且必須單獨備份密鑰、機密和證書。熟悉 Key Vault 的備份和還原指南。", + "waf": "可靠性" + }, + { + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "guid": "0f15640b-31e5-4de6-85a7-d2c652fa09d3", + "link": "https://learn.microsoft.com/azure/key-vault/general/soft-delete-overview#purge-protection", + "service": "Key Vault", "severity": "中等", - "text": "將應用服務活動日誌發送到Log Analytics", - "waf": "安全" + "text": "使用金鑰進行加密時,建議使用清除保護,以防止數據丟失。清除保護是一種可選的 Key Vault 行為,預設情況下未啟用。只有在啟用軟刪除後,才能啟用清除保護。可以通過 CLI、PowerShell 或 Portal 打開它。", + "waf": "可靠性" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "使用區域 VNet 集成、網路安全組和 UDR 的組合來控制出站網路訪問。 流量應路由到 NVA,例如 Azure 防火牆。 確保監控防火牆的日誌。", - "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", - "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", - "service": "App Services", + "arm-service": "Microsoft.KeyVault/vaults", + "checklist": "Azure Key Vault", + "graph": "resources| where type =~ 'microsoft.keyvault/vaults' | extend compliant = (properties.enableRbacAuthorization == true) | distinct id, compliant", + "guid": "d0642c1c-312b-4116-94ab-439e1c836819", + "link": "https://learn.microsoft.com/azure/key-vault/general/rbac-guide?tabs=azure-cli", + "service": "Key Vault", "severity": "中等", - "text": "應控制出站網路訪問", + "text": "建議使用 RBAC 來控制對 Key Vault 的訪問。熟悉 Key Vault 的訪問控制指南。", "waf": "安全" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "可以使用 VNet 集成並使用 VNet NAT 閘道或 NVA(如 Azure 防火牆)來提供穩定的出站 IP。 這允許接收方根據需要根據IP列出允許清單。 請注意,對於與 Azure 服務的通信,通常不需要依賴於 IP 位址,應改用服務終結點等機制。 (此外,在接收端使用專用終結點可避免發生 SNAT,並提供穩定的出站 IP 範圍。", - "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", - "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", - "service": "App Services", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Azure 服務總線高級版提供靜態數據加密。如果您使用自己的金鑰,則數據仍使用 Microsoft 管理的金鑰進行加密,但此外,Microsoft 管理的金鑰將使用客戶管理的密鑰進行加密。", + "guid": "87af4a79-1f89-439b-ba47-768e14c11567", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/configure-customer-managed-key", + "service": "Service Bus", "severity": "低", - "text": "確保與互聯網位址的出站通信具有穩定的IP", + "text": "需要時,在靜態數據加密中使用客戶管理的金鑰選項", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "安全" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "使用應用服務訪問限制、服務終結點或專用終結點的組合來控制入站網路訪問。對於 Web 應用本身和 SCM 網站,可能需要和配置不同的訪問限制。", - "guid": "0725769e-e669-41a4-a34a-c932223ece80", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", - "service": "App Services", - "severity": "高", - "text": "應控制入站網路訪問", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "用戶端應用程式與 Azure 服務總線命名空間之間的通信使用傳輸層安全性 (TLS) 進行加密。Azure 服務總線命名空間允許用戶端使用 TLS 1.0 及更高版本發送和接收數據。若要強制實施更嚴格的安全措施,可以將服務總線命名空間配置為要求用戶端使用較新版本的 TLS 發送和接收數據。", + "guid": "5c1ea55b-46a9-448f-b8ae-7d7e4b475b6c", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/transport-layer-security-enforce-minimum-version", + "service": "Service Bus", + "severity": "中等", + "text": "對請求強制實施最低要求的傳輸層安全性 (TLS) 版本", + "training": "https://learn.microsoft.com/learn/modules/secure-aad-users-with-mfa/", "waf": "安全" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "使用 Web 應用程式防火牆(如應用程式閘道或 Azure Front Door)防範惡意入站流量。 請務必監控 WAF 的日誌。", - "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", - "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", - "service": "App Services", - "severity": "高", - "text": "在應用服務前面使用 WAF", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "創建服務總線命名空間時,會自動為命名空間創建名為 RootManageSharedAccessKey 的 SAS 規則。此策略具有整個命名空間的 Manage 許可權。建議您將此規則視為管理根帳戶,不要在應用程式中使用它。 建議使用 AAD 作為 RBAC 的身份驗證提供程式。", + "guid": "8bcbf59b-ce65-4de8-a03f-97879468d66a", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-sas#shared-access-authorization-policies", + "service": "Service Bus", + "severity": "中等", + "text": "避免在不需要時使用 root 帳戶", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-identities-governance/", "waf": "安全" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "確保僅鎖定對 WAF 的訪問,從而無法繞過 WAF。 結合使用訪問限制、服務終結點和專用終結點。", - "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", - "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", - "service": "App Services", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "在 Azure 應用服務應用程式內或在啟用了 Azure 資源支援的託管實體的虛擬機中運行的服務總線用戶端應用不需要處理 SAS 規則和密鑰或任何其他存取權杖。用戶端應用程式只需要 Service Bus Messaging 命名空間的終結點位址。", + "guid": "786d60f9-6c96-4ad8-a55d-04c2b39c986b", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-managed-service-identity", + "service": "Service Bus", + "severity": "中等", + "text": "如果可能,應用程式應使用託管標識向 Azure 服務總線進行身份驗證。如果沒有,請考慮在 Azure Key Vault 或等效服務中使用存儲憑據(SAS、服務主體憑據)", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "waf": "安全" + }, + { + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "創建許可權時,請對用戶端對 Azure 服務總線的訪問提供精細控制。Azure 服務總線中的許可權可以而且應該限定為單個資源級別,例如佇列、主題或訂閱。", + "guid": "f615658d-e558-4f93-9249-b831112dbd7e", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/authenticate-application#azure-built-in-roles-for-azure-service-bus", + "service": "Service Bus", "severity": "高", - "text": "避免繞過 WAF", + "text": "使用最低許可權數據平面 RBAC", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "安全" }, { - "arm-service": "microsoft.web/sites", - "checklist": "Azure App Service Review", - "description": "在應用服務配置中將最低 TLS 策略設置為 1.2。", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", - "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", - "service": "App Services", + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "Azure 服務總線資源日誌包括操作日誌、虛擬網路和IP篩選日誌。運行時審核日誌捕獲服務總線中各種數據平面訪問操作(例如發送或接收消息)的聚合診斷資訊。", + "guid": "af12e7f9-43f6-4304-922d-929c2b1cd622", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/monitor-service-bus-reference", + "service": "Service Bus", "severity": "中等", - "text": "將最低 TLS 策略設置為 1.2", + "text": "啟用記錄以進行安全調查。使用 Azure Monitor 追蹤資源紀錄和執行時審核紀錄(目前僅在進階層中可用 )", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", + "waf": "安全" + }, + { + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "默認情況下,Azure 服務總線具有公共IP位址,並且可通過Internet訪問。專用終結點允許虛擬網路與 Azure 服務總線之間的流量遍歷 Microsoft 主幹網路。除此之外,如果未使用公有終端節點,則應禁用這些終端節點。", + "guid": "9ae669ca-48e4-4a85-b222-3ece8bb12307", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/private-link-service", + "service": "Service Bus", + "severity": "中等", + "text": "請考慮使用專用終結點訪問 Azure 服務總線,並在適用時禁用公用網路訪問。", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "waf": "安全" + }, + { + "arm-service": "Microsoft.ServiceBus/namespaces", + "checklist": "Service Bus Review Checklist", + "description": "使用IP防火牆,您可以將公有終端節點進一步限製為僅一組 IPv4 位址或 CIDR(無類域間路由)表示法的 IPv4 位址範圍。", + "guid": "ca5f06f1-58e3-4ea3-a92c-2de7e2165c3a", + "link": "https://learn.microsoft.com/azure/service-bus-messaging/service-bus-ip-filtering", + "service": "Service Bus", + "severity": "中等", + "text": "請考慮僅允許從特定IP位址或範圍訪問 Azure 服務總線命名空間", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", "waf": "安全" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "將應用服務配置為僅使用 HTTPS。 這會導致應用服務從 HTTP 重定向到 HTTPS。 強烈建議在代碼或 WAF 中使用 HTTP 嚴格傳輸安全性 (HSTS),這會通知瀏覽器只能使用 HTTPS 訪問網站。", - "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", - "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", - "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", + "guid": "b32e1aa1-4813-4602-88fe-27ca2891f421", + "link": "https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/app-service-web-app/zone-redundant?source=recommendations", "service": "App Services", - "severity": "高", - "text": "僅使用 HTTPS", - "waf": "安全" + "severity": "低", + "text": "有關最佳實踐,請參閱基線高可用性區域冗餘 Web 應用程式體系結構", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "不要在 CORS 配置中使用通配符,因為這允許所有源訪問服務(從而破壞 CORS 的目的)。具體而言,僅允許您希望能夠訪問服務的源。", - "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", - "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", + "guid": "e4b31c6a-2e3f-4df1-8e8b-9c3aa5a27820", + "link": "https://learn.microsoft.com/en-us/azure/app-service/overview-hosting-plans", "service": "App Services", - "severity": "高", - "text": "不得將通配符用於 CORS", - "waf": "安全" + "severity": "中等", + "text": "使用高級層和標準層。這些層支援暫存槽和自動備份。", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "不得在生產環境中啟用遠端調試,因為這會在服務上打開其他埠,從而增加攻擊面。請注意,該服務會在 48 小時後自動轉為遠端調試。", - "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", - "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", - "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", + "guid": "a7e2e6c2-491f-4fa4-a82b-521d0bc3b202", + "link": "https://learn.microsoft.com/en-us/azure/reliability/migrate-app-service", "service": "App Services", "severity": "高", - "text": "關閉遠端調試", - "waf": "安全" + "text": "利用區域適用的可用性區域(需要高級 v2 或 v3 層)", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "啟用 Defender for App Service。 這(除其他威脅外)檢測與已知惡意IP位址的通信。 在操作過程中查看 Defender for App Service 中的建議。", - "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", - "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", + "guid": "1275e4a9-7b6a-43c3-a9cd-5ee18d8995ad", + "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", "service": "App Services", "severity": "中等", - "text": "啟用 Defender for Cloud - Defender for App Service", - "waf": "安全" + "text": "實施健康檢查", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "Azure 在其網路上提供 DDoS 基本保護,可以通過智慧 DDoS 標準功能進行改進,該功能可以瞭解正常的流量模式並檢測異常行為。DDoS 標準適用於虛擬網路,因此必須為應用前面的網路資源(例如應用程式閘道或 NVA)配置它。", - "guid": "223ece80-b123-4071-a541-6415833ea3ad", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "guid": "35a91c5d-4ad6-4d9b-8e0f-c47db9e6d1e7", + "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-backup", "service": "App Services", - "severity": "中等", - "text": "在 WAF VNet 上啟用 DDOS 保護標準", - "waf": "安全" + "severity": "高", + "text": "請參閱 Azure 應用服務的備份和還原最佳做法", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "如果使用 Azure 容器註冊表中儲存的映像,請使用其專用終結點和應用設置“WEBSITE_PULL_IMAGE_OVER_VNET”通過虛擬網络從 Azure 容器註冊表拉取這些映射。", - "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", - "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", + "guid": "e68cd0ec-afc6-4bd8-a27f-7860ad9a0db2", + "link": "https://learn.microsoft.com/en-us/azure/architecture/framework/services/compute/azure-app-service/reliability", "service": "App Services", - "severity": "中等", - "text": "通過虛擬網路拉取容器", - "waf": "安全" + "severity": "高", + "text": "實現 Azure 應用服務可靠性最佳做法", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "按照參與的滲透測試規則對 Web 應用程式進行滲透測試。", - "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", - "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", + "guid": "bd2a865c-0835-4418-bb58-4df91a5a9b3f", + "link": "https://learn.microsoft.com/en-us/azure/app-service/manage-disaster-recovery#recover-app-content-only", "service": "App Services", - "severity": "中等", - "text": "進行滲透測試", - "waf": "安全" + "severity": "低", + "text": "熟悉如何在災難期間將應用服務應用移動到另一個區域", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "部署根據 DevSecOps 實踐驗證和掃描漏洞的受信任代碼。", - "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", - "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", + "guid": "f3d2f1e4-e6d4-4b7a-a5a5-e2a9b2c6f293", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-app-service", "service": "App Services", - "severity": "中等", - "text": "部署經過驗證的代碼", - "waf": "安全" + "severity": "高", + "text": "熟悉 Azure 應用服務中的可靠性支援", + "waf": "可靠性" }, { "arm-service": "microsoft.web/sites", "checklist": "Azure App Service Review", - "description": "使用最新版本的受支援平臺、程式設計語言、協定和框架。", - "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", - "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", + "guid": "c7b5f3d1-0569-4fd2-9f32-c0b64e9c0c5e", + "link": "https://learn.microsoft.com/en-us/azure/azure-functions/dedicated-plan#always-on", "service": "App Services", - "severity": "高", - "text": "使用最新的平臺、語言、協定和框架", - "waf": "安全" + "severity": "中等", + "text": "確保為在應用服務計劃上運行的函數應用啟用“Always On”", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Network/virtualNetworks", - "checklist": "Azure Landing Zone Review", - "guid": "7bc1c396-2461-4698-b57f-30ca69525252", - "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/considerations/regions", - "service": "VNet", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "a3b4d5f6-758c-4f9d-9e1a-d7c6b7e8f9ab", + "link": "https://learn.microsoft.com/en-us/azure/app-service/monitor-instances-health-check", + "service": "App Services", "severity": "中等", - "text": "在多個區域中部署 Azure 登陸區域連接資源,以便可以快速支援多區域應用程式登陸區域和災難恢復方案。", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "text": "使用運行狀況檢查監視應用服務實例", "waf": "可靠性" }, { - "checklist": "Azure Landing Zone Review", - "guid": "70c15989-c726-42c7-b0d3-24b7375b9201", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/considerations-recommendations", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "c7d3e5f9-a19c-4833-8ca6-1dcb0128e129", + "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-overview", + "service": "App Services", "severity": "中等", - "text": "使用一個 Entra 租戶來管理 Azure 資源,除非對多租戶有明確的法規或業務要求。", - "training": "https://learn.microsoft.com/training/modules/deploy-resources-scopes-bicep/2-understand-deployment-scopes", - "waf": "操作" + "text": "使用 Application Insights 可用性測試監視 Web 應用或網站的可用性和回應能力", + "waf": "可靠性" }, { - "checklist": "Azure Landing Zone Review", - "guid": "6309957b-821a-43d1-b9d9-7fcf1802b747", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "guid": "b4e3f2d5-a5c6-4d7e-8b2f-c5d9e7a8f0ea", + "link": "https://learn.microsoft.com/en-us/azure/azure-monitor/app/availability-standard-tests", + "service": "App Services", "severity": "低", - "text": "使用多租戶自動化方法管理您的 Microsoft Entra ID 租戶。", - "training": "https://learn.microsoft.com/entra/architecture/multi-tenant-user-management-introduction/", - "waf": "操作" + "text": "使用 Application Insights 標準測試監視 Web 應用或網站的可用性和回應能力", + "waf": "可靠性" }, { - "checklist": "Azure Landing Zone Review", - "guid": "78e11934-499a-45ed-8ef7-aae5578f0ecf", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "使用 Azure Key Vault 儲存應用程式所需的任何機密。 Key Vault 為儲存機密提供安全且經過審核的環境,並通過 Key Vault SDK 或應用服務 Key Vault 引用與應用服務很好地集成。", + "guid": "834ac932-223e-4ce8-8b12-3071a5416415", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "service": "App Services", "severity": "高", - "text": "使用具有相同 ID 的 Azure Lighthouse 進行多租戶管理。", - "training": "https://learn.microsoft.com/azure/lighthouse/concepts/cross-tenant-management-experience", - "waf": "操作" + "text": "使用 Key Vault 儲存機密", + "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "5d82e6df-6f61-42f2-82e2-3132d293be3d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "使用託管標識通過 Key Vault SDK 或透過應用服務 Key Vault 引用連接到 Key Vault。", + "guid": "833ea3ad-2c2d-4e73-8165-c3acbef4abe1", + "link": "https://learn.microsoft.com/azure/app-service/app-service-key-vault-references", + "service": "App Services", "severity": "高", - "text": "如果向合作夥伴授予管理租戶的許可權,請使用 Azure Lighthouse。", - "training": "https://learn.microsoft.com/azure/lighthouse/how-to/onboard-customer", - "waf": "成本" + "text": "使用託管標識連接到 Key VaultUse Managed Identity to connect to Key Vault", + "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "348ef254-c27d-442e-abba-c7571559ab91", - "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "將應用服務 TLS 證書存儲在 Key Vault 中。", + "guid": "f8d39fda-4776-4831-9c11-5775c2ea55b4", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-certificate", + "service": "App Services", "severity": "高", - "text": "實施與您的雲操作模型相一致的 RBAC 模型。跨管理組和訂閱確定範圍和分配。", - "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "text": "使用 Key Vault 儲存 TLS 證書。", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "12e7f983-f630-4472-8dd6-9c5b5c2622f5", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "處理敏感信息的系統應隔離。 為此,請使用單獨的應用服務計劃或應用服務環境,並考慮使用不同的訂閱或管理組。", + "guid": "6ad48408-ee72-4734-a475-ba18fdbf590c", + "link": "https://learn.microsoft.com/azure/app-service/overview-hosting-plans", + "service": "App Services", "severity": "中等", - "text": "僅對所有帳戶類型使用身份驗證類型 Work or school account。避免使用 Microsoft 帳戶", - "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", + "text": "隔離處理敏感信息的系統", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", - "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "應用服務上的本地磁碟未加密,敏感數據不應存儲在這些磁碟上。 (例如:D:\\\\Local 和 %TMP%)。", + "guid": "e65de8e0-3f9b-4cbd-9682-66abca264f9a", + "link": "https://learn.microsoft.com/azure/app-service/operating-system-functionality#file-access", + "service": "App Services", "severity": "中等", - "text": "僅使用組來分配許可權。如果組管理系統已就位,請將本地組添加到僅 Entra ID 組。", - "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", + "text": "不要將敏感數據存儲在本地磁碟上", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", - "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", - "service": "Entra", - "severity": "高", - "text": "對 Azure 環境具有許可權的任何使用者強制實施 Microsoft Entra ID 條件訪問策略。", - "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "對於經過身份驗證的 Web 應用程式,請使用成熟的標識提供者,例如 Azure AD 或 Azure AD B2C。 利用所選的應用程式框架與此提供程式整合,或使用應用服務身份驗證/授權功能。", + "guid": "919ca0b2-c121-459e-814b-933df574eccc", + "link": "https://learn.microsoft.com/azure/app-service/overview-authentication-authorization", + "service": "App Services", + "severity": "中等", + "text": "使用已建立的身份提供程式進行身份驗證", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", - "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "將代碼從受控且受信任的環境(例如管理良好且安全的 DevOps 部署管道)部署到應用服務。這樣可以避免未經版本控制和驗證從惡意主機部署的代碼。", + "guid": "3f9bcbd4-6826-46ab-aa26-4f9a19aed9c5", + "link": "https://learn.microsoft.com/azure/app-service/deploy-best-practices", + "service": "App Services", "severity": "高", - "text": "對有權訪問 Azure 環境的任何使用者強制實施多重身份驗證。", - "training": "https://learn.microsoft.com/entra/identity/authentication/concept-mandatory-multifactor-authentication", + "text": "從受信任的環境部署", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "14658d35-58fd-4772-99b8-21112df27ee4", - "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", - "service": "Entra", - "severity": "中等", - "text": "強制實施 Microsoft Entra ID Privileged Identity Management (PIM) 以建立零長期訪問和最低許可權。", - "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "禁用 FTP/FTPS 和 WebDeploy/SCM 的基本身份驗證。 這將禁止訪問這些服務,並強制使用 Azure AD 安全終結點進行部署。 請注意,還可以使用 Azure AD 憑據打開 SCM 網站。", + "guid": "5d04c2c3-919c-4a0b-8c12-159e114b933d", + "link": "https://learn.microsoft.com/azure/app-service/deploy-configure-credentials#disable-basic-authentication", + "service": "App Services", + "severity": "高", + "text": "禁用基本身份驗證", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", - "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", - "service": "Entra", - "severity": "中等", - "text": "如果計劃從 Active Directory 域服務切換到 Entra 域服務,請評估所有工作負載的相容性。", - "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "如果可能,請使用託管標識連接到 Azure AD 受保護的資源。 如果無法做到這一點,請將機密存儲在 Key Vault 中,並改用託管標識連接到 Key Vault。", + "guid": "f574eccc-d9bd-43ba-bcda-3b54eb2eb03d", + "link": "https://learn.microsoft.com/azure/app-service/overview-managed-identity?tabs=portal%2Chttp", + "service": "App Services", + "severity": "高", + "text": "使用託管標識連接到資源", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.aad/domainservices' | extend replicaSets = properties.replicaSets | where array_length(replicaSets) < 2 | project name=name, id=id, tags=tags, param1=strcat('replicaSetLocation:', replicaSets[0].location)", - "guid": "0dd4e625-9c4b-4a56-b54a-4357bac12761", - "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", - "service": "Entra", - "severity": "中等", - "text": "使用 Microsoft Entra 域服務時,請使用副本集。副本集將提高託管域的復原能力,並允許您部署到其他區域。", - "training": "https://learn.microsoft.com/training/modules/understand-azure-active-directory/6-examine-azure-domain-services", - "waf": "可靠性" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "如果使用 Azure 容器註冊表中儲存的映像,請使用託管標識拉取這些映像。", + "guid": "d9a25827-18d2-4ddb-8072-5769ee6691a4", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-managed-identity-to-pull-image-from-azure-container-registry", + "service": "App Services", + "severity": "高", + "text": "使用託管標識拉取容器", + "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", - "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "通過配置應用服務的診斷設置,可以將所有遙測數據發送到Log Analytics,作為日誌記錄和監視的中心目標。這允許你監視應用服務的運行時活動,例如 HTTP 日誌、應用程式日誌、平臺日誌等。", + "guid": "47768314-c115-4775-a2ea-55b46ad48408", + "link": "https://learn.microsoft.com/azure/app-service/troubleshoot-diagnostic-logs", + "service": "App Services", "severity": "中等", - "text": "將 Microsoft Entra ID 紀錄與平臺中心的 Azure Monitor 集成。Azure Monitor 允許 Azure 中日誌和監視數據的單一事實來源,為組織提供雲原生選項來滿足日誌收集和保留的要求。", - "training": "https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs", + "text": "將應用服務運行時日誌發送到Log Analytics", "waf": "安全" }, { - "ammp": true, - "checklist": "Azure Landing Zone Review", - "guid": "984a859c-773e-47d2-9162-3a765a917e1f", - "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", - "service": "Entra", - "severity": "高", - "text": "實施緊急訪問或不受限帳戶,以防止租戶範圍的帳戶鎖定。默認情況下,MFA 將於 2024 年 10 月為所有用戶開啟。我們建議更新這些帳戶以使用密鑰 (FIDO2) 或為 MFA 配置基於證書的身份驗證。", - "training": "https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access#exclude-at-least-one-account-from-conditional-access-policies", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "設置診斷設置,將活動日誌發送到Log Analytics,作為日誌記錄和監視的中心目標。這樣,你就可以監視應用服務資源本身上的控制平面活動。", + "guid": "ee72734b-475b-4a18-bdbf-590ce65de8e0", + "link": "https://learn.microsoft.com/azure/azure-monitor/essentials/activity-log", + "service": "App Services", + "severity": "中等", + "text": "將應用服務活動日誌發送到Log Analytics", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "35037e68-9349-4c15-b371-228514f4cdff", - "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", - "service": "Entra", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "使用區域 VNet 集成、網路安全組和 UDR 的組合來控制出站網路訪問。 流量應路由到 NVA,例如 Azure 防火牆。 確保監控防火牆的日誌。", + "guid": "c12159e1-14b9-433d-b574-ecccd9bd3baf", + "link": "https://learn.microsoft.com/azure/app-service/overview-vnet-integration", + "service": "App Services", "severity": "中等", - "text": "請勿將本地同步帳戶用於 Microsoft Entra ID 角色分配,除非你的方案特別需要它。", - "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "text": "應控制出站網路訪問", "waf": "安全" }, { - "checklist": "Azure Landing Zone Review", - "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", - "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", - "service": "Entra", - "severity": "中等", - "text": "使用 Microsoft Entra ID 應用程式代理為遠端使用者提供對應用程式的訪問許可權時,請將其作為平臺資源進行管理,因為每個租戶只能有一個實例。", - "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "可以使用 VNet 集成並使用 VNet NAT 閘道或 NVA(如 Azure 防火牆)來提供穩定的出站 IP。 這允許接收方根據需要根據IP列出允許清單。 請注意,對於與 Azure 服務的通信,通常不需要依賴於 IP 位址,應改用服務終結點等機制。 (此外,在接收端使用專用終結點可避免發生 SNAT,並提供穩定的出站 IP 範圍。", + "guid": "cda3b54e-b2eb-403d-b9a2-582718d2ddb1", + "link": "https://learn.microsoft.com/azure/app-service/networking/nat-gateway-integration", + "service": "App Services", + "severity": "低", + "text": "確保與互聯網位址的出站通信具有穩定的IP", "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", - "checklist": "Azure Landing Zone Review", - "guid": "e8bbac75-7155-49ab-a153-e8908ae28c84", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", - "service": "VNet", - "severity": "中等", - "text": "對於需要最大靈活性的網路方案,請使用中心輻射型網路拓撲。", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "使用應用服務訪問限制、服務終結點或專用終結點的組合來控制入站網路訪問。對於 Web 應用本身和 SCM 網站,可能需要和配置不同的訪問限制。", + "guid": "0725769e-e669-41a4-a34a-c932223ece80", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "service": "App Services", + "severity": "高", + "text": "應控制入站網路訪問", "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", - "checklist": "Azure Landing Zone Review", - "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology", - "service": "VNet", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "使用 Web 應用程式防火牆(如應用程式閘道或 Azure Front Door)防範惡意入站流量。 請務必監控 WAF 的日誌。", + "guid": "b123071a-5416-4415-a33e-a3ad2c2de732", + "link": "https://learn.microsoft.com/azure/app-service/networking/app-gateway-with-service-endpoints", + "service": "App Services", "severity": "高", - "text": "在中心虛擬網路中部署共用網路服務,包括 ExpressRoute 閘道、VPN 閘道和 Azure 防火牆或合作夥伴 NVA。如有必要,還要部署 DNS 服務。", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "成本" + "text": "在應用服務前面使用 WAF", + "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", - "checklist": "Azure Landing Zone Review", - "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", - "service": "VNet", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "確保僅鎖定對 WAF 的訪問,從而無法繞過 WAF。 結合使用訪問限制、服務終結點和專用終結點。", + "guid": "165c3acb-ef4a-4be1-b8d3-9fda47768314", + "link": "https://learn.microsoft.com/azure/app-service/networking-features#access-restrictions", + "service": "App Services", "severity": "高", - "text": "對應用程式登陸區域中的所有公共IP位址使用 DDoS 網路或IP保護計畫。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "text": "避免繞過 WAF", "waf": "安全" }, { - "arm-service": "Microsoft.Compute/virtualMachines", - "checklist": "Azure Landing Zone Review", - "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", - "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", - "service": "NVA", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "在應用服務配置中將最低 TLS 策略設置為 1.2。", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.MinTlsVersion>=1.2) | distinct id,compliant", + "guid": "c115775c-2ea5-45b4-9ad4-8408ee72734b", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-tls-versions", + "service": "App Services", "severity": "中等", - "text": "部署合作夥伴網路技術或 NVA 時,請遵循合作夥伴供應商的指導。", - "waf": "可靠性" - }, - { - "arm-service": "microsoft.network/expressRouteCircuits", - "checklist": "Azure Landing Zone Review", - "guid": "ce463dbb-bc8a-4c2a-aebc-92a43da1dae2", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", - "service": "ExpressRoute", - "severity": "低", - "text": "如果需要在中心輻射型方案中在 ExpressRoute 和 VPN 閘道之間傳輸,請使用 Azure 路由伺服器。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", + "text": "將最低 TLS 策略設置為 1.2", "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualHubs", - "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", - "guid": "91b9d7d5-91e1-4dcb-8f1f-fa7e465646cc", - "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", - "service": "ARS", - "severity": "低", - "text": "如果使用路由伺服器,請對路由伺服器子網使用 /27 前置綴。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "將應用服務配置為僅使用 HTTPS。 這會導致應用服務從 HTTP 重定向到 HTTPS。 強烈建議在代碼或 WAF 中使用 HTTP 嚴格傳輸安全性 (HSTS),這會通知瀏覽器只能使用 HTTPS 訪問網站。", + "graph": "where (type=='microsoft.web/sites' and (kind == 'app' or kind == 'app,linux' )) | extend compliant = (properties.httpsOnly==true) | distinct id,compliant", + "guid": "475ba18f-dbf5-490c-b65d-e8e03f9bcbd4", + "link": "https://learn.microsoft.com/azure/app-service/configure-ssl-bindings#enforce-https", + "service": "App Services", + "severity": "高", + "text": "僅使用 HTTPS", "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", - "checklist": "Azure Landing Zone Review", - "guid": "cc881471-607c-41cc-a0e6-14658dd558f9", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", - "service": "VNet", - "severity": "中等", - "text": "對於跨 Azure 區域具有多個中心輻射型拓撲的網路體系結構,請在中心 VNet 之間使用全域虛擬網路對等互連將區域相互連接。", - "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", - "waf": "性能" + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "不要在 CORS 配置中使用通配符,因為這允許所有源訪問服務(從而破壞 CORS 的目的)。具體而言,僅允許您希望能夠訪問服務的源。", + "guid": "68266abc-a264-4f9a-89ae-d9c55d04c2c3", + "link": "https://learn.microsoft.com/azure/app-service/app-service-web-tutorial-rest-api", + "service": "App Services", + "severity": "高", + "text": "不得將通配符用於 CORS", + "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", - "checklist": "Azure Landing Zone Review", - "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", - "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", - "service": "VNet", + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "不得在生產環境中啟用遠端調試,因為這會在服務上打開其他埠,從而增加攻擊面。請注意,該服務會在 48 小時後自動轉為遠端調試。", + "graph": "appserviceresources | where type =~ 'microsoft.web/sites/config' | extend compliant = (properties.RemoteDebuggingEnabled == false) | distinct id,compliant", + "guid": "d9bd3baf-cda3-4b54-bb2e-b03dd9a25827", + "link": "https://learn.microsoft.com/azure/app-service/configure-common#configure-general-settings", + "service": "App Services", + "severity": "高", + "text": "關閉遠端調試", + "waf": "安全" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "啟用 Defender for App Service。 這(除其他威脅外)檢測與已知惡意IP位址的通信。 在操作過程中查看 Defender for App Service 中的建議。", + "guid": "18d2ddb1-0725-4769-be66-91a4834ac932", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-app-service-introduction", + "service": "App Services", "severity": "中等", - "text": "使用適用於網路的 Azure Monitor 監視 Azure 上網路的端到端狀態。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", - "waf": "操作" + "text": "啟用 Defender for Cloud - Defender for App Service", + "waf": "安全" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "Azure 在其網路上提供 DDoS 基本保護,可以通過智慧 DDoS 標準功能進行改進,該功能可以瞭解正常的流量模式並檢測異常行為。DDoS 標準適用於虛擬網路,因此必須為應用前面的網路資源(例如應用程式閘道或 NVA)配置它。", + "guid": "223ece80-b123-4071-a541-6415833ea3ad", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "service": "App Services", + "severity": "中等", + "text": "在 WAF VNet 上啟用 DDOS 保護標準", + "waf": "安全" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "如果使用 Azure 容器註冊表中儲存的映像,請使用其專用終結點和應用設置“WEBSITE_PULL_IMAGE_OVER_VNET”通過虛擬網络從 Azure 容器註冊表拉取這些映射。", + "guid": "2c2de732-165c-43ac-aef4-abe1f8d39fda", + "link": "https://learn.microsoft.com/azure/app-service/configure-custom-container#use-an-image-from-a-network-protected-registry", + "service": "App Services", + "severity": "中等", + "text": "通過虛擬網路拉取容器", + "waf": "安全" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "按照參與的滲透測試規則對 Web 應用程式進行滲透測試。", + "guid": "eb2eb03d-d9a2-4582-918d-2ddb10725769", + "link": "https://learn.microsoft.com/azure/security/fundamentals/pen-testing", + "service": "App Services", + "severity": "中等", + "text": "進行滲透測試", + "waf": "安全" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "部署根據 DevSecOps 實踐驗證和掃描漏洞的受信任代碼。", + "guid": "19aed9c5-5d04-4c2c-9919-ca0b2c12159e", + "link": "https://learn.microsoft.com/azure/architecture/solution-ideas/articles/devsecops-in-azure", + "service": "App Services", + "severity": "中等", + "text": "部署經過驗證的代碼", + "waf": "安全" + }, + { + "arm-service": "microsoft.web/sites", + "checklist": "Azure App Service Review", + "description": "使用最新版本的受支援平臺、程式設計語言、協定和框架。", + "guid": "114b933d-f574-4ecc-ad9b-d3bafcda3b54", + "link": "https://learn.microsoft.com/azure/app-service/overview-patch-os-runtime", + "service": "App Services", + "severity": "高", + "text": "使用最新的平臺、語言、協定和框架", + "waf": "安全" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant", - "guid": "0e7c28ec-9366-4572-83b0-f4664b1d944a", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", + "guid": "7bc1c396-2461-4698-b57f-30ca69525252", + "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/considerations/regions", "service": "VNet", "severity": "中等", - "text": "如果一個區域中的分支網路超過 400 個,請部署一個額外的中心以繞過 VNet 對等互連限制 (500) 和可通過 ExpressRoute 播發的最大前綴數 (1000)。", + "text": "在多個區域中部署 Azure 登陸區域連接資源,以便可以快速支援多區域應用程式登陸區域和災難恢復方案。", "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", "waf": "可靠性" }, { - "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant", - "guid": "3d457936-e9b7-41eb-bdff-314b26450b12", - "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", - "service": "VNet", + "guid": "70c15989-c726-42c7-b0d3-24b7375b9201", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/considerations-recommendations", + "service": "Entra", "severity": "中等", - "text": "將每個路由表的路由數限制為 400。", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "可靠性" + "text": "使用一個 Entra 租戶來管理 Azure 資源,除非對多租戶有明確的法規或業務要求。", + "training": "https://learn.microsoft.com/training/modules/deploy-resources-scopes-bicep/2-understand-deployment-scopes", + "waf": "操作" }, { - "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)", - "guid": "c76cb5a2-abe2-11ed-afa1-0242ac120002", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", - "service": "VNet", + "guid": "6309957b-821a-43d1-b9d9-7fcf1802b747", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/automation", + "service": "Entra", + "severity": "低", + "text": "使用多租戶自動化方法管理您的 Microsoft Entra ID 租戶。", + "training": "https://learn.microsoft.com/entra/architecture/multi-tenant-user-management-introduction/", + "waf": "操作" + }, + { + "checklist": "Azure Landing Zone Review", + "guid": "78e11934-499a-45ed-8ef7-aae5578f0ecf", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/multi-tenant/lighthouse", + "service": "Entra", "severity": "高", - "text": "配置 VNet 對等互連時,請使用「允許流量流向遠端虛擬網路」設置。", - "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", - "waf": "可靠性" + "text": "使用具有相同 ID 的 Azure Lighthouse 進行多租戶管理。", + "training": "https://learn.microsoft.com/azure/lighthouse/concepts/cross-tenant-management-experience", + "waf": "操作" }, { "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)", - "guid": "9dcd6250-9c4a-4382-aa9b-5b84c64fc1fe", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", - "service": "Load Balancers", + "guid": "5d82e6df-6f61-42f2-82e2-3132d293be3d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/landing-zone/design-area/azure-billing-microsoft-customer-agreement#design-recommendations", + "service": "Entra", "severity": "高", - "text": "將標準負載均衡器 SKU 與區域冗餘部署配合使用,選擇標準 SKU 負載均衡器可通過可用性區域和區域復原能力增強可靠性,確保部署能夠承受區域和區域故障。與 Basic 不同,它支援全域負載平衡並提供 SLA。", - "waf": "可靠性" + "text": "如果向合作夥伴授予管理租戶的許可權,請使用 Azure Lighthouse。", + "training": "https://learn.microsoft.com/azure/lighthouse/how-to/onboard-customer", + "waf": "成本" }, { "checklist": "Azure Landing Zone Review", - "graph": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))", - "guid": "48682fb1-1e86-4458-a686-518ebd47393d", - "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", - "service": "Load Balancers", + "guid": "348ef254-c27d-442e-abba-c7571559ab91", + "link": "https://learn.microsoft.com/azure/role-based-access-control/overview", + "service": "Entra", "severity": "高", - "text": "確保負載均衡器後端池至少包含兩個實例,在後端部署至少包含兩個實例的 Azure 負載均衡器可以防止單點故障並支援可伸縮性。", - "waf": "可靠性" + "text": "實施與您的雲操作模型相一致的 RBAC 模型。跨管理組和訂閱確定範圍和分配。", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-macsec", - "service": "ExpressRoute", + "guid": "12e7f983-f630-4472-8dd6-9c5b5c2622f5", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-planning#identify-microsoft-accounts-in-administrative-roles-that-need-to-be-switched-to-work-or-school-accounts", + "service": "Entra", "severity": "中等", - "text": "使用 ExpressRoute Direct 時,請配置 MACsec,以便在組織路由器和 MSEE 之間的第二層加密流量。該圖顯示了這種加密流程。", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "text": "僅對所有帳戶類型使用身份驗證類型 Work or school account。避免使用 Microsoft 帳戶", + "training": "https://learn.microsoft.com/learn/modules/explore-basic-services-identity-types/", "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", - "link": "https://learn.microsoft.com/azure/vpn-gateway/site-to-site-vpn-private-peering", - "service": "ExpressRoute", + "guid": "4b69bad3-3aad-45e8-a68e-1d76667313b4", + "link": "https://learn.microsoft.com/azure/active-directory/fundamentals/active-directory-groups-create-azure-portal", + "service": "Entra", "severity": "中等", - "text": "對於無法使用MACsec的情況(例如,不使用ExpressRoute Direct),請使用 VPN 閘道通過 ExpressRoute 專用對等互連建立 IPsec 隧道。", - "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "text": "僅使用組來分配許可權。如果組管理系統已就位,請將本地組添加到僅 Entra ID 組。", + "training": "https://learn.microsoft.com/learn/paths/manage-identity-and-access/", "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "558fd772-49b8-4211-82df-27ee412e7f98", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "service": "ExpressRoute", + "guid": "53e8908a-e28c-484c-93b6-b7808b9fe5c4", + "link": "https://learn.microsoft.com/azure/active-directory/conditional-access/overview", + "service": "Entra", "severity": "高", - "text": "確保 Azure 區域和本地位置之間沒有使用重疊的 IP 位址空間。", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "text": "對 Azure 環境具有許可權的任何使用者強制實施 Microsoft Entra ID 條件訪問策略。", + "training": "https://learn.microsoft.com/learn/modules/plan-implement-administer-conditional-access/", "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr", - "guid": "3f630472-2dd6-49c5-a5c2-622f54b69bad", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "service": "VNet", - "severity": "中等", - "text": "使用私有互聯網的位址分配範圍 (RFC 1918) 中的IP位址。", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "guid": "1049d403-a923-4c34-94d0-0018ac6a9e01", + "link": "https://learn.microsoft.com/azure/active-directory/authentication/concept-mfa-howitworks", + "service": "Entra", + "severity": "高", + "text": "對有權訪問 Azure 環境的任何使用者強制實施多重身份驗證。", + "training": "https://learn.microsoft.com/entra/identity/authentication/concept-mandatory-multifactor-authentication", "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant", - "guid": "33aad5e8-c68e-41d7-9667-313b4f5664b5", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", - "service": "VNet", - "severity": "高", - "text": "確保IP位址空間不會浪費,不要創建不必要的大型虛擬網路(例如/16)。", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", - "waf": "性能" + "guid": "14658d35-58fd-4772-99b8-21112df27ee4", + "link": "https://learn.microsoft.com/azure/active-directory/privileged-identity-management/pim-configure", + "service": "Entra", + "severity": "中等", + "text": "強制實施 Microsoft Entra ID Privileged Identity Management (PIM) 以建立零長期訪問和最低許可權。", + "training": "https://learn.microsoft.com/learn/modules/azure-ad-privileged-identity-management/", + "waf": "安全" }, { - "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "f348ef25-4c27-4d42-b8bb-ac7571559ab9", - "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", - "service": "VNet", - "severity": "高", - "text": "不要對生產和災難恢復網站使用重疊的IP位址範圍。", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "可靠性" + "guid": "8b9fe5c4-1049-4d40-9a92-3c3474d00018", + "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", + "service": "Entra", + "severity": "中等", + "text": "如果計劃從 Active Directory 域服務切換到 Entra 域服務,請評估所有工作負載的相容性。", + "training": "https://learn.microsoft.com/learn/modules/implement-hybrid-identity-windows-server/", + "waf": "安全" }, { "checklist": "Azure Landing Zone Review", - "graph": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)", - "guid": "0c47f486-656d-4699-8c30-edef5b8a93c4", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone", - "service": "Public IP Addresses", - "severity": "高", - "text": "使用標準 SKU 和區域冗餘 IP(如果適用),Azure 中的公共 IP 位址可以是標準 SKU,以非區域、區域或區域冗餘的形式提供。區域冗餘IP可跨所有區域訪問,可抵禦任何單個區域故障,從而提供更高的彈性。", - "training": "https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing", + "graph": "resources | where type == 'microsoft.aad/domainservices' | extend replicaSets = properties.replicaSets | where array_length(replicaSets) < 2 | project name=name, id=id, tags=tags, param1=strcat('replicaSetLocation:', replicaSets[0].location)", + "guid": "0dd4e625-9c4b-4a56-b54a-4357bac12761", + "link": "https://learn.microsoft.com/entra/identity/domain-services/overview", + "service": "Entra", + "severity": "中等", + "text": "使用 Microsoft Entra 域服務時,請使用副本集。副本集將提高託管域的復原能力,並允許您部署到其他區域。", + "training": "https://learn.microsoft.com/training/modules/understand-azure-active-directory/6-examine-azure-domain-services", "waf": "可靠性" }, { - "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "153e8908-ae28-4c84-a33b-6b7808b9fe5c", - "link": "https://learn.microsoft.com/azure/dns/private-dns-getstarted-portal", - "service": "DNS", + "guid": "1cf0b8da-70bd-44d0-94af-8d99cfc89ae1", + "link": "https://learn.microsoft.com/azure/active-directory/reports-monitoring/concept-activity-logs-azure-monitor", + "service": "Entra", "severity": "中等", - "text": "對於只需要在 Azure 中進行名稱解析的環境,請使用 Azure 專用 DNS 進行解析,並使用委託區域進行名稱解析(例如“azure.contoso.com”)。", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "操作" + "text": "將 Microsoft Entra ID 紀錄與平臺中心的 Azure Monitor 集成。Azure Monitor 允許 Azure 中日誌和監視數據的單一事實來源,為組織提供雲原生選項來滿足日誌收集和保留的要求。", + "training": "https://learn.microsoft.com/entra/identity/monitoring-health/howto-integrate-activity-logs-with-azure-monitor-logs", + "waf": "安全" }, { - "arm-service": "Microsoft.Network/dnsZones", + "ammp": true, "checklist": "Azure Landing Zone Review", - "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", - "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", - "service": "DNS", - "severity": "中等", - "text": "對於需要跨 Azure 和本地進行名稱解析且沒有 Active Directory 等現有企業 DNS 服務的環境,請使用 Azure DNS 專用解析程式將 DNS 請求路由到 Azure 或本地 DNS 伺服器。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", + "guid": "984a859c-773e-47d2-9162-3a765a917e1f", + "link": "https://learn.microsoft.com/azure/active-directory/roles/security-emergency-access", + "service": "Entra", + "severity": "高", + "text": "實施緊急訪問或不受限帳戶,以防止租戶範圍的帳戶鎖定。默認情況下,MFA 將於 2024 年 10 月為所有用戶開啟。我們建議更新這些帳戶以使用密鑰 (FIDO2) 或為 MFA 配置基於證書的身份驗證。", + "training": "https://learn.microsoft.com/entra/identity/role-based-access-control/security-emergency-access#exclude-at-least-one-account-from-conditional-access-policies", "waf": "安全" }, { - "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "1e6a83de-5de3-42c1-a924-81607d5d1e4e", - "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", - "service": "DNS", - "severity": "低", - "text": "需要並部署自己的 DNS 的特殊工作負載(例如 Red Hat OpenShift)應使用其首選的 DNS 解決方案。", - "training": "https://learn.microsoft.com/training/courses/az-700t00", - "waf": "操作" + "guid": "35037e68-9349-4c15-b371-228514f4cdff", + "link": "https://learn.microsoft.com/azure/active-directory/roles/best-practices", + "service": "Entra", + "severity": "中等", + "text": "請勿將本地同步帳戶用於 Microsoft Entra ID 角色分配,除非你的方案特別需要它。", + "training": "https://learn.microsoft.com/learn/modules/design-identity-security-strategy/", + "waf": "安全" }, { - "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "614658d3-558f-4d77-849b-821112df27ee", - "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", - "service": "DNS", - "severity": "高", - "text": "為 Azure DNS 啟用自動註冊,以自動管理虛擬網路中部署的虛擬機的 DNS 記錄的生命週期。", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "操作" + "guid": "d5d1e4e6-1465-48d3-958f-d77249b82111", + "link": "https://learn.microsoft.com/azure/active-directory/app-proxy/application-proxy", + "service": "Entra", + "severity": "中等", + "text": "使用 Microsoft Entra ID 應用程式代理為遠端使用者提供對應用程式的訪問許可權時,請將其作為平臺資源進行管理,因為每個租戶只能有一個實例。", + "training": "https://learn.microsoft.com/learn/paths/implement-applications-external-access-azure-ad/", + "waf": "安全" }, { - "arm-service": "Microsoft.Network/dnsZones", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "18c80eb0-582a-4198-bf5c-d8800b2d263b", - "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale#private-link-and-dns-integration-in-hub-and-spoke-network-architectures", - "service": "DNS", + "guid": "e8bbac75-7155-49ab-a153-e8908ae28c84", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/enterprise-scale/network-topology-and-connectivity", + "service": "VNet", "severity": "中等", - "text": "實施一個計劃,用於管理多個 Azure 區域之間的 DNS 解析以及服務故障轉移到另一個區域時", - "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", - "waf": "可靠性" + "text": "對於需要最大靈活性的網路方案,請使用中心輻射型網路拓撲。", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "安全" }, { - "arm-service": "microsoft.network/bastionHosts", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", - "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", - "service": "Bastion", - "severity": "中等", - "text": "使用 Azure Bastion 安全地連接到您的網路。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", - "waf": "安全" + "guid": "7dd61623-a364-4a90-9eca-e48ebd54cd7d", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology", + "service": "VNet", + "severity": "高", + "text": "在中心虛擬網路中部署共用網路服務,包括 ExpressRoute 閘道、VPN 閘道和 Azure 防火牆或合作夥伴 NVA。如有必要,還要部署 DNS 服務。", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "waf": "成本" }, { - "arm-service": "microsoft.network/bastionHosts", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant", - "guid": "6eab9eb6-762b-485e-8ea8-15aa5dba0bd0", - "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", - "service": "Bastion", - "severity": "中等", - "text": "在子網 /26 或更大的子網中使用 Azure Bastion。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", + "guid": "143b16c3-1d7a-4a9b-9470-4489a8042d88", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-overview", + "service": "VNet", + "severity": "高", + "text": "對應用程式登陸區域中的所有公共IP位址使用 DDoS 網路或IP保護計畫。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", "waf": "安全" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "Microsoft.Compute/virtualMachines", "checklist": "Azure Landing Zone Review", - "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", - "service": "WAF", + "guid": "e2e8abac-3571-4559-ab91-53e89f89dc7b", + "link": "https://learn.microsoft.com/azure/architecture/reference-architectures/dmz/nva-ha", + "service": "NVA", "severity": "中等", - "text": "使用 Azure Front Door 和 WAF 策略跨 Azure 區域為到登陸區域的入站 HTTP/S 連接提供全域保護。", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", - "waf": "安全" + "text": "部署合作夥伴網路技術或 NVA 時,請遵循合作夥伴供應商的指導。", + "waf": "可靠性" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "service": "WAF", + "guid": "ce463dbb-bc8a-4c2a-aebc-92a43da1dae2", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager#to-enable-transit-routing-between-expressroute-and-azure-vpn", + "service": "ExpressRoute", "severity": "低", - "text": "使用 Azure Front Door 和 Azure 應用程式閘道幫助保護 HTTP/S 應用時,請使用 Azure Front Door 中的 WAF 策略。鎖定 Azure 應用程式閘道以僅接收來自 Azure Front Door 的流量。", - "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "text": "如果需要在中心輻射型方案中在 ExpressRoute 和 VPN 閘道之間傳輸,請使用 Azure 路由伺服器。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", "waf": "安全" }, { - "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", + "arm-service": "Microsoft.Network/virtualHubs", "checklist": "Azure Landing Zone Review", - "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", - "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", - "service": "WAF", - "severity": "高", - "text": "當入站 HTTP/S 連接需要 WAF 和其他反向代理時,請將它們部署在登陸區虛擬網路中,並與它們保護並公開給 Internet 的應用程式一起部署。", - "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant", + "guid": "91b9d7d5-91e1-4dcb-8f1f-fa7e465646cc", + "link": "https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1", + "service": "ARS", + "severity": "低", + "text": "如果使用路由伺服器,請對路由伺服器子網使用 /27 前置綴。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-route-server/", "waf": "安全" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", + "guid": "cc881471-607c-41cc-a0e6-14658dd558f9", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#can-i-create-a-peering-connection-to-a-vnet-in-a-different-region", "service": "VNet", - "severity": "高", - "text": "使用 Azure DDoS 網路或 IP 保護計劃來幫助保護虛擬網路中的公共 IP 位址終結點。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "安全" + "severity": "中等", + "text": "對於跨 Azure 區域具有多個中心輻射型拓撲的網路體系結構,請在中心 VNet 之間使用全域虛擬網路對等互連將區域相互連接。", + "training": "https://learn.microsoft.com/learn/paths/azure-administrator-manage-virtual-networks/", + "waf": "性能" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "b034c01e-110b-463a-b36e-e3346e57f225", - "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/default-outbound-access", + "guid": "4722d929-c1b1-4cd6-81f5-4b29bade39ad", + "link": "https://learn.microsoft.com/azure/azure-monitor/insights/network-insights-overview", "service": "VNet", - "severity": "高", - "text": "規劃如何在即將到來的重大更改之前管理您的網路出站流量配置和策略。2025 年 9 月 30 日,新部署的預設出站訪問將停用,僅允許顯式訪問配置。", - "training": "https://learn.microsoft.com/training/modules/configure-virtual-networks/", + "severity": "中等", + "text": "使用適用於網路的 Azure Monitor 監視 Azure 上網路的端到端狀態。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "操作" + }, + { + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant", + "guid": "0e7c28ec-9366-4572-83b0-f4664b1d944a", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", + "service": "VNet", + "severity": "中等", + "text": "如果一個區域中的分支網路超過 400 個,請部署一個額外的中心以繞過 VNet 對等互連限制 (500) 和可通過 ExpressRoute 播發的最大前綴數 (1000)。", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", "waf": "可靠性" }, { "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "b1c82a3f-2320-4dfa-8972-7ae4823c8930", - "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", + "graph": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant", + "guid": "3d457936-e9b7-41eb-bdff-314b26450b12", + "link": "https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits", "service": "VNet", - "severity": "高", - "text": "添加診斷設置以保存所有受保護的公有IP位址(DDoS IP或網路保護)的 DDoS 相關日誌。", - "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", - "waf": "安全" + "severity": "中等", + "text": "將每個路由表的路由數限制為 400。", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Authorization/policyDefinitions", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "3c5a808d-c695-4c14-a63c-c7ab7a510e41", - "link": "https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies#corp", - "service": "Policy", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)", + "guid": "c76cb5a2-abe2-11ed-afa1-0242ac120002", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering", + "service": "VNet", "severity": "高", - "text": "確保有一個策略分配來拒絕直接連接到虛擬機的公有IP位址。 如果特定 VM 上需要公共 IP,請使用排除項。", - "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", - "waf": "安全" + "text": "配置 VNet 對等互連時,請使用「允許流量流向遠端虛擬網路」設置。", + "training": "https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/", + "waf": "可靠性" }, { - "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", - "service": "ExpressRoute", - "severity": "中等", - "text": "使用 ExpressRoute 作為與 Azure 的主要連接。 使用 VPN 作為備份連接的源。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "性能" + "graph": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)", + "guid": "9dcd6250-9c4a-4382-aa9b-5b84c64fc1fe", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", + "service": "Load Balancers", + "severity": "高", + "text": "將標準負載均衡器 SKU 與區域冗餘部署配合使用,選擇標準 SKU 負載均衡器可通過可用性區域和區域復原能力增強可靠性,確保部署能夠承受區域和區域故障。與 Basic 不同,它支援全域負載平衡並提供 SLA。", + "waf": "可靠性" }, { - "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "description": "您可以使用 AS 路徑預置和連接權重來影響從 Azure 到本地的流量,並使用您自己的路由器中的所有 BGP 屬性來影響從本地到 Azure 的流量。", - "guid": "f29812b2-363c-4efe-879b-599de0d5973c", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", - "service": "ExpressRoute", - "severity": "中等", - "text": "使用多個 ExpressRoute 線路或多個本地位置時,請使用 BGP 屬性來優化路由。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "graph": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))", + "guid": "48682fb1-1e86-4458-a686-518ebd47393d", + "link": "https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant", + "service": "Load Balancers", + "severity": "高", + "text": "確保負載均衡器後端池至少包含兩個實例,在後端部署至少包含兩個實例的 Azure 負載均衡器可以防止單點故障並支援可伸縮性。", "waf": "可靠性" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant", - "guid": "d4cd21b0-8813-47f5-b6c4-cfd3e504547c", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku", + "guid": "de0d5973-cd4c-4d21-a088-137f5e6c4cfd", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-macsec", "service": "ExpressRoute", "severity": "中等", - "text": "根據頻寬和性能要求為 ExpressRoute/VPN 閘道選擇正確的 SKU。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "性能" + "text": "使用 ExpressRoute Direct 時,請配置 MACsec,以便在組織路由器和 MSEE 之間的第二層加密流量。該圖顯示了這種加密流程。", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "安全" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant", - "guid": "7025b442-f6e9-4af6-b11f-c9574916016f", - "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", + "guid": "ed301d6e-872e-452e-9611-cc58b5a4b151", + "link": "https://learn.microsoft.com/azure/vpn-gateway/site-to-site-vpn-private-peering", "service": "ExpressRoute", - "severity": "高", - "text": "確保僅在達到與成本相稱的頻寬時才使用無限數據 ExpressRoute 線路。", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "成本" + "severity": "中等", + "text": "對於無法使用MACsec的情況(例如,不使用ExpressRoute Direct),請使用 VPN 閘道通過 ExpressRoute 專用對等互連建立 IPsec 隧道。", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id", - "guid": "f4e7926a-ec35-476e-a412-5dd17136bd62", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", + "guid": "558fd772-49b8-4211-82df-27ee412e7f98", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", "service": "ExpressRoute", "severity": "高", - "text": "如果你的線路對等互連位置支援本地 SKU 的 Azure 區域,請利用 ExpressRoute 的本地 SKU 來降低線路的成本。", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "成本" + "text": "確保 Azure 區域和本地位置之間沒有使用重疊的 IP 位址空間。", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant", - "guid": "2447ec66-138a-4720-8f1c-e16ed301d6e8", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways", - "service": "ExpressRoute", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr", + "guid": "3f630472-2dd6-49c5-a5c2-622f54b69bad", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "service": "VNet", "severity": "中等", - "text": "在支援的 Azure 區域中部署區域冗餘 ExpressRoute 閘道。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "可靠性" + "text": "使用私有互聯網的位址分配範圍 (RFC 1918) 中的IP位址。", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", - "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", - "service": "ExpressRoute", - "severity": "中等", - "text": "對於需要高於 10 Gbps 的頻寬或專用 10/100 Gbps 埠的方案,請使用 ExpressRoute Direct。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "graph": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant", + "guid": "33aad5e8-c68e-41d7-9667-313b4f5664b5", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing", + "service": "VNet", + "severity": "高", + "text": "確保IP位址空間不會浪費,不要創建不必要的大型虛擬網路(例如/16)。", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", "waf": "性能" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", - "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", - "service": "ExpressRoute", - "severity": "中等", - "text": "當需要低延遲,或者從本地到 Azure 的輸送量必須大於 10 Gbps 時,請啟用 FastPath 以從數據路徑繞過 ExpressRoute 閘道。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "性能" + "guid": "f348ef25-4c27-4d42-b8bb-ac7571559ab9", + "link": "https://learn.microsoft.com/azure/site-recovery/concepts-on-premises-to-azure-networking#retain-ip-addresses", + "service": "VNet", + "severity": "高", + "text": "不要對生產和災難恢復網站使用重疊的IP位址範圍。", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "可靠性" }, { - "arm-service": "microsoft.network/virtualNetworkGateways", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant", - "guid": "4d873974-8b66-42d6-b15f-512a65498f6d", - "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", - "service": "VPN", - "severity": "中等", - "text": "使用區域冗餘 VPN 閘道將分支或遠端位置連接到 Azure(如果可用)。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", + "graph": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)", + "guid": "0c47f486-656d-4699-8c30-edef5b8a93c4", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone", + "service": "Public IP Addresses", + "severity": "高", + "text": "使用標準 SKU 和區域冗餘 IP(如果適用),Azure 中的公共 IP 位址可以是標準 SKU,以非區域、區域或區域冗餘的形式提供。區域冗餘IP可跨所有區域訪問,可抵禦任何單個區域故障,從而提供更高的彈性。", + "training": "https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing", "waf": "可靠性" }, { - "arm-service": "microsoft.network/virtualNetworkGateways", + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "45866df8-cf85-4ca9-bbe2-65ec1478919e", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", - "service": "VPN", + "guid": "153e8908-ae28-4c84-a33b-6b7808b9fe5c", + "link": "https://learn.microsoft.com/azure/dns/private-dns-getstarted-portal", + "service": "DNS", "severity": "中等", - "text": "在本地使用冗餘 VPN 設備(主動/主動或主動/被動)。", - "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", - "waf": "可靠性" + "text": "對於只需要在 Azure 中進行名稱解析的環境,請使用 Azure 專用 DNS 進行解析,並使用委託區域進行名稱解析(例如“azure.contoso.com”)。", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "操作" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "718cb437-b060-2589-8856-2e93a5c6633b", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", - "service": "ExpressRoute", + "guid": "41049d40-3a92-43c3-974d-00018ac6a9e0", + "link": "https://learn.microsoft.com/azure/dns/dns-private-resolver-overview", + "service": "DNS", + "severity": "中等", + "text": "對於需要跨 Azure 和本地進行名稱解析且沒有 Active Directory 等現有企業 DNS 服務的環境,請使用 Azure DNS 專用解析程式將 DNS 請求路由到 Azure 或本地 DNS 伺服器。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-dns-private-resolver/", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Network/dnsZones", + "checklist": "Azure Landing Zone Review", + "guid": "1e6a83de-5de3-42c1-a924-81607d5d1e4e", + "link": "https://learn.microsoft.com/azure/virtual-network/virtual-networks-name-resolution-for-vms-and-role-instances", + "service": "DNS", + "severity": "低", + "text": "需要並部署自己的 DNS 的特殊工作負載(例如 Red Hat OpenShift)應使用其首選的 DNS 解決方案。", + "training": "https://learn.microsoft.com/training/courses/az-700t00", + "waf": "操作" + }, + { + "arm-service": "Microsoft.Network/dnsZones", + "checklist": "Azure Landing Zone Review", + "guid": "614658d3-558f-4d77-849b-821112df27ee", + "link": "https://learn.microsoft.com/azure/dns/private-dns-autoregistration", + "service": "DNS", "severity": "高", - "text": "如果使用 ExpressRoute Direct,請考慮使用連接到本地 Azure 區域的 ExpressRoute 本地線路以節省成本。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "成本" + "text": "為 Azure DNS 啟用自動註冊,以自動管理虛擬網路中部署的虛擬機的 DNS 記錄的生命週期。", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "操作" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/dnsZones", "checklist": "Azure Landing Zone Review", - "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", - "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", - "service": "ExpressRoute", + "guid": "18c80eb0-582a-4198-bf5c-d8800b2d263b", + "link": "https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/private-link-and-dns-integration-at-scale#private-link-and-dns-integration-in-hub-and-spoke-network-architectures", + "service": "DNS", "severity": "中等", - "text": "當需要流量隔離或專用頻寬時(例如用於分離生產和非生產環境),請使用不同的 ExpressRoute 線路。它將幫助您確保隔離的路由域並減輕嘈雜的鄰居風險。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "安全" + "text": "實施一個計劃,用於管理多個 Azure 區域之間的 DNS 解析以及服務故障轉移到另一個區域時", + "training": "https://learn.microsoft.com/learn/paths/az-104-manage-virtual-networks/", + "waf": "可靠性" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "microsoft.network/bastionHosts", "checklist": "Azure Landing Zone Review", - "guid": "b30e38c3-f298-412b-8363-cefe179b599d", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", - "service": "ExpressRoute", + "guid": "ee1ac551-c4d5-46cf-b035-d0a3c50d87ad", + "link": "https://learn.microsoft.com/azure/bastion/bastion-overview", + "service": "Bastion", "severity": "中等", - "text": "使用內置的 Express Route Insights 監控 ExpressRoute 的可用性和利用率。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "操作" + "text": "使用 Azure Bastion 安全地連接到您的網路。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "microsoft.network/bastionHosts", "checklist": "Azure Landing Zone Review", - "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", - "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", - "service": "ExpressRoute", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant", + "guid": "6eab9eb6-762b-485e-8ea8-15aa5dba0bd0", + "link": "https://learn.microsoft.com/azure/bastion/bastion-faq#subnet", + "service": "Bastion", "severity": "中等", - "text": "使用連接監視器進行跨網路的連接監控,尤其是本地和 Azure 之間的連接。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "操作" + "text": "在子網 /26 或更大的子網中使用 Azure Bastion。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-bastion/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)", - "guid": "e0d5973c-d4cd-421b-8881-37f5e6c4cfd3", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution", - "service": "ExpressRoute", + "guid": "1d7aa9b6-4704-4489-a804-2d88e79d17b7", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/afds-overview", + "service": "WAF", "severity": "中等", - "text": "使用來自不同對等互連位置的 ExpressRoute 線路以實現冗餘。", - "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "可靠性" + "text": "使用 Azure Front Door 和 WAF 策略跨 Azure 區域為到登陸區域的入站 HTTP/S 連接提供全域保護。", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "guid": "cf3fe65c-fec0-495a-8edc-9675200f2add", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager", - "service": "ExpressRoute", - "severity": "中等", - "text": "如果僅使用單個 ExpressRoute 線路,請使用網站到網站 VPN 作為 ExpressRoute 的故障轉移。", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", - "waf": "可靠性" + "guid": "3b22a5a6-7e7a-48ed-9b30-e38c3f29812b", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "WAF", + "severity": "低", + "text": "使用 Azure Front Door 和 Azure 應用程式閘道幫助保護 HTTP/S 應用時,請使用 Azure Front Door 中的 WAF 策略。鎖定 Azure 應用程式閘道以僅接收來自 Azure Front Door 的流量。", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "microsoft.network/frontdoorwebApplicationFirewalls", "checklist": "Azure Landing Zone Review", - "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))", - "guid": "72105cc8-aaea-4ee1-8c7a-ad25977afcaf", - "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub", - "service": "ExpressRoute", + "guid": "2363cefe-179b-4599-be0d-5973cd4cd21b", + "link": "https://learn.microsoft.com/azure/web-application-firewall/ag/ag-overview", + "service": "WAF", "severity": "高", - "text": "如果您在 GatewaySubnet 中使用路由表,請確保傳播閘道路由。", - "waf": "可靠性" + "text": "當入站 HTTP/S 連接需要 WAF 和其他反向代理時,請將它們部署在登陸區虛擬網路中,並與它們保護並公開給 Internet 的應用程式一起部署。", + "training": "https://learn.microsoft.com/learn/paths/architect-network-infrastructure/", + "waf": "安全" }, { - "arm-service": "microsoft.network/expressRouteCircuits", + "arm-service": "Microsoft.Network/virtualNetworks", "checklist": "Azure Landing Zone Review", - "guid": "d581a947-69a2-4783-942e-9df3664324c8", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", - "service": "ExpressRoute", + "guid": "088137f5-e6c4-4cfd-9e50-4547c2447ec6", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", + "service": "VNet", "severity": "高", - "text": "如果使用 ExpressRoute,則本地路由應該是動態的:如果連接失敗,它應收斂到線路的剩餘連接。理想情況下,負載應在兩個連接之間共用,即主動/主動,但也支持主動/被動。", - "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "text": "使用 Azure DDoS 網路或 IP 保護計劃來幫助保護虛擬網路中的公共 IP 位址終結點。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "b034c01e-110b-463a-b36e-e3346e57f225", + "link": "https://learn.microsoft.com/azure/virtual-network/ip-services/default-outbound-access", + "service": "VNet", + "severity": "高", + "text": "規劃如何在即將到來的重大更改之前管理您的網路出站流量配置和策略。2025 年 9 月 30 日,新部署的預設出站訪問將停用,僅允許顯式訪問配置。", + "training": "https://learn.microsoft.com/training/modules/configure-virtual-networks/", "waf": "可靠性" }, + { + "arm-service": "Microsoft.Network/virtualNetworks", + "checklist": "Azure Landing Zone Review", + "guid": "b1c82a3f-2320-4dfa-8972-7ae4823c8930", + "link": "https://learn.microsoft.com/azure/ddos-protection/ddos-protection-reference-architectures", + "service": "VNet", + "severity": "高", + "text": "添加診斷設置以保存所有受保護的公有IP位址(DDoS IP或網路保護)的 DDoS 相關日誌。", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "arm-service": "Microsoft.Authorization/policyDefinitions", + "checklist": "Azure Landing Zone Review", + "guid": "3c5a808d-c695-4c14-a63c-c7ab7a510e41", + "link": "https://github.com/Azure/Enterprise-Scale/wiki/ALZ-Policies#corp", + "service": "Policy", + "severity": "高", + "text": "確保有一個策略分配來拒絕直接連接到虛擬機的公有IP位址。 如果特定 VM 上需要公共 IP,請使用排除項。", + "training": "https://learn.microsoft.com/training/modules/configure-azure-policy/", + "waf": "安全" + }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "b258f058-b9f6-46cd-b28d-990106f0c3f8", - "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute", + "guid": "359c373e-7dd6-4162-9a36-4a907ecae48e", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", "service": "ExpressRoute", "severity": "中等", - "text": "確保 ExpressRoute 線路的兩個物理連結連接到網路中的兩個不同的邊緣設備。", + "text": "使用 ExpressRoute 作為與 Azure 的主要連接。 使用 VPN 作為備份連接的源。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", - "waf": "可靠性" + "waf": "性能" }, { "arm-service": "microsoft.network/expressRouteCircuits", "checklist": "Azure Landing Zone Review", - "guid": "fe2a1b53-6fbd-4c67-b58a-85d7c7a0afcb", - "link": "https://learn.microsoft.com/azure/expressroute/expressroute-bfd", + "description": "您可以使用 AS 路徑預置和連接權重來影響從 Azure 到本地的流量,並使用您自己的路由器中的所有 BGP 屬性來影響從本地到 Azure 的流量。", + "guid": "f29812b2-363c-4efe-879b-599de0d5973c", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-routing", "service": "ExpressRoute", "severity": "中等", - "text": "確保在客戶或供應商邊緣路由設備上啟用和配置雙向轉發檢測 (BFD)。", + "text": "使用多個 ExpressRoute 線路或多個本地位置時,請使用 BGP 屬性來優化路由。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant", + "guid": "d4cd21b0-8813-47f5-b6c4-cfd3e504547c", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku", + "service": "ExpressRoute", + "severity": "中等", + "text": "根據頻寬和性能要求為 ExpressRoute/VPN 閘道選擇正確的 SKU。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "性能" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant", + "guid": "7025b442-f6e9-4af6-b11f-c9574916016f", + "link": "https://learn.microsoft.com/azure/expressroute/plan-manage-cost", + "service": "ExpressRoute", + "severity": "高", + "text": "確保僅在達到與成本相稱的頻寬時才使用無限數據 ExpressRoute 線路。", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "成本" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id", + "guid": "f4e7926a-ec35-476e-a412-5dd17136bd62", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local", + "service": "ExpressRoute", + "severity": "高", + "text": "如果你的線路對等互連位置支援本地 SKU 的 Azure 區域,請利用 ExpressRoute 的本地 SKU 來降低線路的成本。", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "成本" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant", + "guid": "2447ec66-138a-4720-8f1c-e16ed301d6e8", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways", + "service": "ExpressRoute", + "severity": "中等", + "text": "在支援的 Azure 區域中部署區域冗餘 ExpressRoute 閘道。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "72e52e36-11cc-458b-9a4b-1511e43a58a9", + "link": "https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure", + "service": "ExpressRoute", + "severity": "中等", + "text": "對於需要高於 10 Gbps 的頻寬或專用 10/100 Gbps 埠的方案,請使用 ExpressRoute Direct。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "性能" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "c2299c4d-7b57-4d0c-9555-62f2b3e4563a", + "link": "https://learn.microsoft.com/azure/expressroute/about-fastpath", + "service": "ExpressRoute", + "severity": "中等", + "text": "當需要低延遲,或者從本地到 Azure 的輸送量必須大於 10 Gbps 時,請啟用 FastPath 以從數據路徑繞過 ExpressRoute 閘道。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "性能" + }, + { + "arm-service": "microsoft.network/virtualNetworkGateways", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant", + "guid": "4d873974-8b66-42d6-b15f-512a65498f6d", + "link": "https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway", + "service": "VPN", + "severity": "中等", + "text": "使用區域冗餘 VPN 閘道將分支或遠端位置連接到 Azure(如果可用)。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/virtualNetworkGateways", + "checklist": "Azure Landing Zone Review", + "guid": "45866df8-cf85-4ca9-bbe2-65ec1478919e", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-highlyavailable", + "service": "VPN", + "severity": "中等", + "text": "在本地使用冗餘 VPN 設備(主動/主動或主動/被動)。", + "training": "https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "718cb437-b060-2589-8856-2e93a5c6633b", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-erdirect-about", + "service": "ExpressRoute", + "severity": "高", + "text": "如果使用 ExpressRoute Direct,請考慮使用連接到本地 Azure 區域的 ExpressRoute 本地線路以節省成本。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "成本" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "8042d88e-79d1-47b7-9b22-a5a67e7a8ed4", + "link": "https://learn.microsoft.com/azure/architecture/framework/services/networking/expressroute/reliability", + "service": "ExpressRoute", + "severity": "中等", + "text": "當需要流量隔離或專用頻寬時(例如用於分離生產和非生產環境),請使用不同的 ExpressRoute 線路。它將幫助您確保隔離的路由域並減輕嘈雜的鄰居風險。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "安全" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "b30e38c3-f298-412b-8363-cefe179b599d", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-monitoring-metrics-alerts", + "service": "ExpressRoute", + "severity": "中等", + "text": "使用內置的 Express Route Insights 監控 ExpressRoute 的可用性和利用率。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "操作" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "5bf68dc9-325e-4873-bf88-f8214ef2e5d2", + "link": "https://learn.microsoft.com/azure/expressroute/how-to-configure-connection-monitor", + "service": "ExpressRoute", + "severity": "中等", + "text": "使用連接監視器進行跨網路的連接監控,尤其是本地和 Azure 之間的連接。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "操作" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)", + "guid": "e0d5973c-d4cd-421b-8881-37f5e6c4cfd3", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution", + "service": "ExpressRoute", + "severity": "中等", + "text": "使用來自不同對等互連位置的 ExpressRoute 線路以實現冗餘。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "cf3fe65c-fec0-495a-8edc-9675200f2add", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-howto-coexist-resource-manager", + "service": "ExpressRoute", + "severity": "中等", + "text": "如果僅使用單個 ExpressRoute 線路,請使用網站到網站 VPN 作為 ExpressRoute 的故障轉移。", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "graph": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))", + "guid": "72105cc8-aaea-4ee1-8c7a-ad25977afcaf", + "link": "https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub", + "service": "ExpressRoute", + "severity": "高", + "text": "如果您在 GatewaySubnet 中使用路由表,請確保傳播閘道路由。", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "d581a947-69a2-4783-942e-9df3664324c8", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute#active-active-connections", + "service": "ExpressRoute", + "severity": "高", + "text": "如果使用 ExpressRoute,則本地路由應該是動態的:如果連接失敗,它應收斂到線路的剩餘連接。理想情況下,負載應在兩個連接之間共用,即主動/主動,但也支持主動/被動。", + "training": "https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "b258f058-b9f6-46cd-b28d-990106f0c3f8", + "link": "https://learn.microsoft.com/azure/expressroute/designing-for-high-availability-with-expressroute", + "service": "ExpressRoute", + "severity": "中等", + "text": "確保 ExpressRoute 線路的兩個物理連結連接到網路中的兩個不同的邊緣設備。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.network/expressRouteCircuits", + "checklist": "Azure Landing Zone Review", + "guid": "fe2a1b53-6fbd-4c67-b58a-85d7c7a0afcb", + "link": "https://learn.microsoft.com/azure/expressroute/expressroute-bfd", + "service": "ExpressRoute", + "severity": "中等", + "text": "確保在客戶或供應商邊緣路由設備上啟用和配置雙向轉發檢測 (BFD)。", "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", "waf": "可靠性" }, @@ -2684,50 +3052,252 @@ "waf": "操作" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "ab5351f6-383a-45ed-9c5e-b143b16db40a", - "link": "https://learn.microsoft.com/azure/aks/use-windows-hpc", - "service": "AKS", - "severity": "低", - "text": "如果 AKS Windows 工作負載需要,可以使用 HostProcess 容器", - "waf": "可靠性" + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "禁用圖像匯出以防止數據洩露。請注意,這將阻止將映射導入到另一個 ACR 實例中。", + "guid": "ab91932c-9fc9-4d1b-a880-37f5e6bfcb9e", + "link": "https://learn.microsoft.com/azure/container-registry/data-loss-prevention", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend exportPolicyStatus = properties.policies.exportPolicy.status | extend compliant = iif(exportPolicyStatus =~ 'Disabled', true, false) | project acrName, acrId, exportPolicyStatus, compliant", + "service": "ACR", + "severity": "高", + "text": "禁用 Azure Container Registry 映射導出", + "waf": "安全" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "a280dcf5-90ce-465d-b8e1-3f9ccbd46926", - "link": "https://learn.microsoft.com/azure/azure-functions/functions-kubernetes-keda", - "service": "AKS", - "severity": "低", - "text": "如果運行事件驅動的工作負載,請使用KEDA", - "waf": "性能" + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "通過為 Azure Container Registry 啟用 Azure Policy 來啟用審核合規性可見性", + "guid": "d503547c-d447-4e82-9128-a7100f1cac6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-azure-policy", + "service": "ACR", + "severity": "高", + "text": "為 Azure 容器註冊表啟用 Azure 策略", + "waf": "安全" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", - "link": "https://dapr.io/", - "service": "AKS", - "severity": "低", - "text": "使用 Dapr 簡化微服務開發", - "waf": "操作" + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure Key Vault (AKV) 用於存儲簽名密鑰,該金鑰可通過表示法 AKV 外掛程式 (azure-kv) 來對容器映像和其他專案進行簽名和驗證。Azure 容器註冊表 (ACR) 允許您使用 az?or?oras? 附加這些簽名。CLI 命令。", + "guid": "d345293c-7639-4637-a551-c5c04e401955", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-tutorial-sign-build-push", + "service": "ACR", + "severity": "高", + "text": "使用符號對容器進行簽名和驗證 (Notary v2)", + "waf": "安全" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (sku.tier=='Paid') | distinct id,compliant", - "guid": "71d41e36-10cc-457b-9a4b-1410d4395898", - "link": "https://learn.microsoft.com/azure/aks/uptime-sla", - "service": "AKS", - "severity": "高", - "text": "使用 SLA 支援的 AKS 產品/服務", - "waf": "可靠性" + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "Azure 容器註冊表會自動加密存儲的映像和其他專案。默認情況下,Azure 使用服務託管密鑰自動加密靜態註冊表內容。通過使用客戶管理的金鑰,您可以使用額外的加密層來補充預設加密。", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant", + "guid": "0bd05dc2-efd5-4d76-8d41-d2500cc47b49", + "link": "https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys", + "service": "ACR", + "severity": "中等", + "text": "使用客戶管理的金鑰加密註冊表", + "waf": "安全" }, { - "arm-service": "microsoft.containerservice/managedClusters", - "checklist": "Azure AKS Review", - "guid": "c1288b3c-6a57-4cfc-9444-51e1a3d3453a", + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "使用託管標識保護來自用戶端應用程式的 ACRPull/Push RBAC 訪問", + "guid": "8f42d78e-79dc-47b3-9bd2-a1a27e7a8e90", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "高", + "text": "使用託管標識而不是服務主體進行連接", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "默認情況下,本地管理員帳戶處於禁用狀態,不應啟用。請改用基於 Token 或 RBAC 的訪問方法", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "be0e38ce-e297-411b-b363-caaab79b198d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity", + "service": "ACR", + "severity": "高", + "text": "禁用管理平面訪問的本地身份驗證", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "禁用管理員帳戶並將 RBAC 角色分配給 ACR 拉取/推送操作的主體", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant", + "guid": "387e5ced-126c-4d13-8af5-b20c6998a646", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli", + "service": "ACR", + "severity": "高", + "text": "分配AcrPull和AcrPush RBAC角色,而不是授予身份主體管理訪問許可權", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "禁用匿名拉取/推送訪問", + "graph": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant", + "guid": "e338997e-41c7-47d7-acf6-a62a1194956d", + "link": "https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access", + "service": "ACR", + "severity": "中等", + "text": "禁用匿名拉取訪問許可權", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "令牌身份驗證不支援分配給 AAD 主體。任何可以訪問令牌的人都可以使用提供的任何令牌", + "guid": "698dc3a2-fd27-4b2e-8870-1a1252beedf6", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-authentication?tabs=azure-cli", + "service": "ACR", + "severity": "高", + "text": "禁用存儲庫範圍的訪問令牌", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "將容器映像部署到受信任網路中專用終結點後面的 ACR", + "guid": "b3bec3d4-f343-47c1-936d-b55f27a71eee", + "service": "ACR", + "severity": "高", + "text": "從受信任的環境部署映像", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "只有具有 ACR 受眾的令牌才能用於身份驗證。為 ACR 啟用條件存取策略時使用", + "guid": "3a041fd3-2947-498b-8288-b3c6a56ceb54", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-enable-conditional-access-policy", + "service": "ACR", + "severity": "中等", + "text": "禁用 Azure ARM 受眾令牌進行身份驗證", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "設置一個診斷設置,將『repositoryEvents』和『LoginEvents』發送到Log Analytics作為記錄和監控的中心目標。這允許您監控 ACR 資源本身的控制平面活動。", + "guid": "8a488cde-c486-42bc-9bd2-1be77f26e5e6", + "link": "https://learn.microsoft.com/azure/container-registry/monitor-service", + "service": "ACR", + "severity": "中等", + "text": "啟用診斷日誌記錄", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "服務支援通過使用服務級別 IP ACL 篩選規則(而不是 NSG 或 Azure 防火牆)或使用“禁用公用網络訪問”切換開關來禁用公用網络訪問", + "guid": "21d41d25-00b7-407a-b9ea-b40fd3290798", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-private-link", + "service": "ACR", + "severity": "中等", + "text": "使用專用連結控制入站網路訪問", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "如果使用專用連結保護入站網路訪問,則禁用公用網路訪問", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant", + "guid": "cd289ced-6b17-4db8-8554-62f2aee4553a", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access", + "service": "ACR", + "severity": "中等", + "text": "禁用公共網路訪問", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "只有 ACR Premium SKU 支援專用連結訪問", + "graph": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant", + "guid": "fc833934-8b26-42d6-ac5f-512925498f6d", + "link": "https://learn.microsoft.com/azure/container-registry/container-registry-skus", + "service": "ACR", + "severity": "中等", + "text": "使用支援專用連結的 Azure 容器註冊表 SKU(高級 SKU)", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "應使用適用於容器的 Azure Defender 或等效服務來掃描容器映像中的漏洞", + "guid": "bad37dac-43bc-46ce-8d7a-a9b24604489a", + "link": "https://learn.microsoft.com/azure/defender-for-cloud/defender-for-containers-introduction", + "service": "ACR", + "severity": "低", + "text": "啟用 Defender for Containers 以掃描 Azure 容器註冊表中的漏洞", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "部署根據 DevSecOps 實踐進行驗證和漏洞掃描的可信代碼。", + "guid": "4451e1a2-d345-4293-a763-9637a551c5c0", + "service": "ACR", + "severity": "中等", + "text": "部署經過驗證的容器映像", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerregistry/registries", + "checklist": "Azure Container Registry Security Review", + "description": "使用最新版本的受支援平臺、程式設計語言、協定和框架。", + "guid": "4e401955-387e-45ce-b126-cd132af5b20c", + "service": "ACR", + "severity": "高", + "text": "使用最新的平臺、語言、協定和框架", + "waf": "安全" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "ab5351f6-383a-45ed-9c5e-b143b16db40a", + "link": "https://learn.microsoft.com/azure/aks/use-windows-hpc", + "service": "AKS", + "severity": "低", + "text": "如果 AKS Windows 工作負載需要,可以使用 HostProcess 容器", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "a280dcf5-90ce-465d-b8e1-3f9ccbd46926", + "link": "https://learn.microsoft.com/azure/azure-functions/functions-kubernetes-keda", + "service": "AKS", + "severity": "低", + "text": "如果運行事件驅動的工作負載,請使用KEDA", + "waf": "性能" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "26886d20-b66c-457b-a591-19bf8e8f5c58", + "link": "https://dapr.io/", + "service": "AKS", + "severity": "低", + "text": "使用 Dapr 簡化微服務開發", + "waf": "操作" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "graph": "where type=='microsoft.containerservice/managedclusters' | extend compliant = (sku.tier=='Paid') | distinct id,compliant", + "guid": "71d41e36-10cc-457b-9a4b-1410d4395898", + "link": "https://learn.microsoft.com/azure/aks/uptime-sla", + "service": "AKS", + "severity": "高", + "text": "使用 SLA 支援的 AKS 產品/服務", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.containerservice/managedClusters", + "checklist": "Azure AKS Review", + "guid": "c1288b3c-6a57-4cfc-9444-51e1a3d3453a", "link": "https://learn.microsoft.com/azure/aks/operator-best-practices-scheduler", "service": "AKS", "severity": "低", @@ -4404,6 +4974,46 @@ "text": "Azure 機器人服務在全域和區域服務的主動-主動模式下運行。發生中斷時,無需檢測錯誤或管理服務。Azure 機器人服務在多區域地理體系結構中自動執行自動故障轉移和自動恢復。對於歐盟機器人區域服務,Azure 機器人服務在歐洲境內提供兩個完整區域,並提供主動/主動複製,以確保冗餘。對於全球機器人服務,所有可用的區域/地理位置都可以作為全球足跡。", "waf": "可靠性" }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "65285269-440b-44be-9d3e-0844276d4bdc", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", + "service": "Redis", + "severity": "高", + "text": "為 Azure Cache for Redis 啟用區域冗餘。Azure Cache for Redis 支持高級層和企業層中的區域冗餘配置。區域冗餘緩存可以將其節點放置在同一區域的不同 Azure 可用性區域中。它消除了數據中心或可用區中斷作為單點故障,並提高了緩存的整體可用性。", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", + "service": "Redis", + "severity": "中等", + "text": "為 Azure Cache for Redis 實例配置數據持久性。由於緩存數據存儲在記憶體中,因此多個節點的罕見意外故障可能會導致所有數據被丟棄。為避免完全丟失數據,Redis 持久性允許您定期拍攝記憶體數據的快照,並將其存儲到您的存儲帳戶中。", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", + "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", + "service": "Redis", + "severity": "中等", + "text": "使用異地冗餘存儲帳戶來保存 Azure Cache for Redis 數據,或者在異地冗餘不可用的情況下使用區域冗餘", + "waf": "可靠性" + }, + { + "arm-service": "microsoft.cache/redis", + "checklist": "Redis Resiliency checklist", + "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", + "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", + "service": "Redis", + "severity": "中等", + "text": "為高級 Azure Cache for Redis 實例配置被動異地複製。異地複製是一種用於連結兩個或多個 Azure Cache for Redis 實例的機制,通常跨兩個 Azure 區域。異地複製主要用於跨區域災難恢復。兩個高級層緩存實例通過異地複製進行連接,以便對主緩存進行讀取和寫入,並將該數據複製到輔助緩存。", + "waf": "可靠性" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "DataBricks Review Checklist", @@ -5085,6 +5695,17 @@ "text": "限制本地使用者對 Synapse 上的 sql 工作負載使用", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "不需要其他配置,因為此功能已在預設部署中啟用。", + "guid": "21d41d25-00c8-417b-b9ea-c41fd3390798", + "link": "https://learn.microsoft.com/azure/event-hubs/transport-layer-security-configure-minimum-version", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "加密傳輸中的敏感數據", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5096,6 +5717,15 @@ "text": "使用託管標識對服務進行身份驗證", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "bc288bec-6a17-4ca7-8444-51e1add3452a", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "默認啟用靜態數據加密", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5106,6 +5736,17 @@ "text": "分離和限制高許可權/管理使用者,並啟用 MFA 和條件策略", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "使用 Keyvaults 儲存 CMK", + "guid": "ec723923-7a15-41c5-ab5e-401915387e5c", + "link": "https://learn.microsoft.com/azure/event-hubs/configure-customer-managed-key?tabs=Key-Vault", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "需要時,在靜態數據加密中使用客戶管理的金鑰選項", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5138,6 +5779,16 @@ "text": "使用託管 vnet 工作區限制通過公共 Internet 的訪問", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "使用 Microsoft Entra ID 作為預設身份驗證方法。", + "guid": "a9c26d9c-42bb-45bd-8c69-99a246e3389a", + "service": "Azure Event Hubs", + "severity": "高", + "text": "使用 Microsoft Entra ID 作為預設身份驗證方法,並盡可能禁用本地訪問", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5149,6 +5800,16 @@ "text": "配置專用終結點以連接到外部服務並禁用公有訪問", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "使用 Microsoft Entra ID 作為預設身份驗證方法。", + "guid": "7e42c77d-78cb-46a2-8ad1-9f916e698d8f", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "使用託管標識對服務進行身份驗證", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5159,6 +5820,15 @@ "text": "如果啟用公網訪問,強烈建議配置 IP 防火牆規則", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "adfe27bd-e187-401a-a352-baa9b68a088c", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "配置條件訪問策略以限制對數據平面的訪問", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5169,6 +5839,16 @@ "text": "如果正在處理不應離開公司網路的敏感數據,請在 vnet 中部署 SHIR VM", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "限制金鑰和 secert 的公開", + "guid": "9a80822b-8eb9-4d1b-a77f-26e5e6beba8e", + "service": "Azure Event Hubs", + "severity": "高", + "text": "使用 Azure Key Vault 儲存機密和密碼。", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5180,6 +5860,37 @@ "text": "開啟資料洩露保護 (DEP)", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "d4f3437c-c336-4d81-9f27-a71efe1b9b5d", + "service": "Azure Event Hubs", + "severity": "高", + "text": "分離和限制高許可權/管理使用者", + "waf": "安全" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "創建事件中心命名空間時,會自動為該命名空間創建名為 RootManageSharedAccessKey 的策略規則。此策略具有整個命名空間的manage許可權。建議您將此規則視為管理 root 帳戶,不要在應用程式中使用它。您可以通過 PowerShell 或 Azure CLI 在門戶中為命名空間的 Configure (配置) 選項卡中創建其他策略規則。避免使用本地身份驗證方法或帳戶,應盡可能禁用這些方法或帳戶。請盡可能使用 Azure AD 進行身份驗證。", + "guid": "9de0d5d7-21d4-41d2-900c-817bf9eac41f", + "link": "https://learn.microsoft.com/azure/event-hubs/authenticate-shared-access-signature", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "使用共用訪問簽名 (SAS) 驗證對事件中心資源的訪問並限制本地使用者", + "waf": "安全" + }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "使用 Azure 基於角色的訪問控制 (Azure RBAC) 通過內置角色分配來管理 Azure 資源訪問。可以將 Azure RBAC 角色分配給使用者、組、服務主體和託管標識。", + "guid": "387e5ced-127d-4d14-8b06-b20c6999a646", + "link": "https://learn.microsoft.com/azure/event-hubs/authorize-access-azure-active-directory", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "使用 Azure RBAC 精細化訪問", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5191,6 +5902,16 @@ "text": "使用客戶管理的 Workspace 金鑰進行靜態數據加密", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "服務支援通過使用服務級別 IP ACL 篩選規則(而不是 NSG 或 Azure 防火牆)或使用“禁用公用網络訪問”切換開關來禁用公用網络訪問。", + "guid": "f3389a7e-42c7-48e7-ac06-a62a2194956e", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "禁用公共網路訪問", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5202,6 +5923,15 @@ "text": "傳輸中的數據加密", "waf": "安全" }, + { + "arm-service": "microsoft.eventhub/namespaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "6a8dc4a2-fe27-4b2e-8870-1a1352beedf7", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "使用 Vnet 隔離受限網路上的流量", + "waf": "安全" + }, { "arm-service": "Microsoft.Synapse/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5213,36 +5943,190 @@ "waf": "安全" }, { - "arm-service": "Microsoft.DataFactory/datafactories", + "arm-service": "microsoft.eventhub/namespaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "限制使用本地身份驗證方法進行數據平面訪問。相反,請使用 Microsoft Entra ID 作為預設身份驗證方法來控制數據平面訪問。", - "guid": "0bdf4cc2-efc4-4d76-8c31-d25ffbb47a39", - "service": "Azure Data Factory", - "severity": "高", - "text": "在必要時限制使用本地使用者", + "guid": "9b488dee-c496-42cc-9cd2-1bf77f26e5e6", + "link": "https://learn.microsoft.com/azure/event-hubs/private-link-service", + "service": "Azure Event Hubs", + "severity": "中等", + "text": "為支援專用連結功能的所有 Azure 資源部署專用終結點,以便為資源建立專用訪問點。", "waf": "安全" }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "託管身份消除了管理憑證的需要。託管標識在連接到支援 Microsoft Entra 身份驗證的資源時為服務實例提供標識。", - "guid": "3a040ed3-2947-498b-8178-a2c5a46ceb54", - "link": "https://learn.microsoft.com/azure/data-factory/data-factory-service-identity", + "description": "您可以將憑據或機密值存儲在 Azure Key Vault 中,並在管道執行期間使用它們以傳遞給您的活動。", + "guid": "a3aec2c4-e243-46b0-936d-b55e17960eee", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", "service": "Azure Data Factory", "severity": "中等", - "text": "使用託管標識對服務進行身份驗證", + "text": "在管道活動中使用 Azure Key Vault 機密", "waf": "安全" }, { - "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", - "description": "如果日常管理操作不需要,請禁用或限制任何本地管理員帳戶,以供緊急使用。", + "description": "Fabric 使用工作區控制數據訪問。在工作區中,數據以 Fabric 項的形式顯示,除非您授予使用者對工作區的訪問許可權,否則使用者無法查看或使用項(數據)。您可以在許可權模型 中找到有關工作區和項目許可權的更多資訊。", + "guid": "b3bed3d5-f353-47c1-946d-c56028a71ffe", + "link": "https://learn.microsoft.com/fabric/security/permission-model", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "使用 Workspace 角色向使用者提供對數據的訪問許可權", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "OneLake RBAC 使用角色分配將許可權應用於其成員。", + "guid": "1bd05dd2-e0d5-4d77-8d41-e3611cc57b4a", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "在 Onelake 上使用 RBAC 提供對 Tables/Files Onelake 中數據的精細訪問", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "考慮使用者在快捷方式的目標和源位置的訪問許可權", + "guid": "4b1410d4-3958-498c-8288-b3c6a57cfc64", + "link": "https://learn.microsoft.com/fabric/onelake/security/data-access-control-model#shortcuts", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "使用快捷方式時,用戶的使用者身份也應具有對快捷方式目標位置的訪問許可權", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "並非所有使用者都需要使用角色訪問整個工作區,因此請限制授予整個工作區的角色,並且僅使用共用項功能或 Fabric 中的管理許可權將項共用給使用者", + "guid": "4451e1a3-d345-43a3-a763-9637a552d5c1", + "link": "https://learn.microsoft.com/fabric/get-started/share-items", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "限制向使用者提供工作區級別角色,而是僅向使用者共享專案", + "training": "https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "使用 RLS、CLS 和動態數據遮罩等功能來增強您對 SQL 工作負載的數據安全要求。", + "guid": "5e401965-387e-45ce-b127-dd142b06b20c", + "link": "https://learn.microsoft.com/fabric/data-warehouse/tutorial-row-level-security", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "通過在 Warehouse 和 SQL 分析終端節點上定義 RLS、CLS 和動態數據掩碼來限制對數據的訪問", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "使用 Power BI 上的 RLS 和 OLS 等功能,在語義模型上獲得更多安全功能", + "guid": "6999a646-f338-49a7-b42c-78e78c06a62a", + "link": "https://learn.microsoft.com/fabric/security/service-admin-row-level-security", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "通過在Power BI中的語義模型上定義 RLS 和 OLS 來限制對數據的訪問", + "training": "https://learn.microsoft.com/learn/paths/secure-application-delivery/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "在 Fabric 中,存儲在 OneLake 中的所有數據都是靜態加密的", + "guid": "2194956e-6a8d-4c4a-8fe2-7b2e28701a13", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "加密靜態數據", + "training": "https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "在 Microsoft 服務之間通過公共 Internet 傳輸的數據始終至少使用 TLS 1.2 進行加密。Fabric 會盡可能協商到 TLS 1.3。", + "guid": "52beedf7-9b48-48de-bc49-62cc3cd21bf7", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "加密傳輸中的數據", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "限制使用本地身份驗證方法進行數據平面訪問。相反,請使用 Microsoft Entra ID 作為預設身份驗證方法來控制數據平面訪問。", + "guid": "0bdf4cc2-efc4-4d76-8c31-d25ffbb47a39", + "service": "Azure Data Factory", + "severity": "高", + "text": "在必要時限制使用本地使用者", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "無需執行任何操作。連接到 Fabric 的每個請求都使用 Microsoft Entra ID 進行身份驗證,允許使用者從公司辦公室、在家工作或遠端位置安全地連接到 Fabric。", + "guid": "7f26e5e6-b3be-4d3d-9f35-37c1346dc560", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "使用 Microsoft Entra ID 作為預設身份驗證方法", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "託管身份消除了管理憑證的需要。託管標識在連接到支援 Microsoft Entra 身份驗證的資源時為服務實例提供標識。", + "guid": "3a040ed3-2947-498b-8178-a2c5a46ceb54", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-service-identity", + "service": "Azure Data Factory", + "severity": "中等", + "text": "使用託管標識對服務進行身份驗證", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric 工作區標識是可與 Fabric 工作區關聯的自動託管服務主體。可以在除 My workspaces(我的工作區)之外的任何工作區的工作區設置中創建工作區身份。系統會自動為工作區標識分配工作區參與者角色,並有權訪問工作區專案。 限制:使用 Workspace Identity 作為身份驗證方法時,寫入快捷方式目標失敗。帶有 workspace-identity-authentication 的連接只能在 Onelake 快捷方式和數據管道中使用。", + "guid": "28a71ffe-1bd0-45dd-8e0d-5d771d41e361", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "使用 workspace identity 對服務進行身份驗證", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "如果日常管理操作不需要,請禁用或限制任何本地管理員帳戶,以供緊急使用。", "guid": "4350d092-d234-4292-a752-8537a551c5bf", "service": "Azure Data Factory", "severity": "高", "text": "分離和限制高許可權/管理使用者,並啟用 MFA 和條件策略", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "授予對存儲帳戶的標識許可權", + "guid": "1cc57b4a-4b14-410d-9395-898c2288b3c6", + "link": "https://learn.microsoft.com/fabric/security/workspace-identity-authenticate#step-2-grant-the-identity-permissions-on-the-storage-account", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "將存儲帳戶上的 RBAC 角色提供給託管標識以建立成功連接", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "guid": "4e4f1854-287d-45cd-a126-cc032af5b1fc", + "service": "Azure Data Factory", + "severity": "中等", + "text": "禁用通過公共 Internet 的訪問,並配置防火牆規則或受信任的服務規則", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "具有工作區標識的結構工作區可以通過 OneLake 快捷方式的受信任工作區訪問許可權安全地讀取或寫入啟用了防火牆的 Azure Data Lake Storage Gen2 帳戶。", + "guid": "a57cfc64-4451-4e1a-9d34-53a3c7639637", + "link": "https://learn.microsoft.com/fabric/security/security-trusted-workspace-access", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "配置受信任的工作區訪問許可權以訪問防火牆後面的存儲帳戶", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5252,6 +6136,17 @@ "text": "如果正在處理不應離開公司網路的敏感數據,請在 vnet 中部署 SHIR VM", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "託管虛擬網路是由 Microsoft Fabric 為每個 Fabric 工作區創建和管理的虛擬網路。託管虛擬網路為 Fabric Spark 工作負載提供網路隔離,這意味著計算集群部署在專用網路中,不再是共用虛擬網路的一部分。它僅支援 Fabric 中的 Spark 工作負載。", + "guid": "a552d5c1-5e40-4196-9387-e5ced127dd14", + "link": "https://learn.microsoft.com/fabric/security/security-managed-vnets-fabric-overview", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "如果您有網路隔離需求,請使用託管 vnet 選項", + "training": "https://learn.microsoft.com/learn/paths/implement-resource-mgmt-security/", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5262,6 +6157,17 @@ "text": "使用託管 vnet IR 限制 Azure Integration Runtime 通過公共 Internet 的訪問", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "託管專用終端節點是一項功能,允許從 Fabric Spark 工作負載對數據源進行安全和私有訪問。您不能將 Starter Pool 與託管 PE 一起使用", + "guid": "6f4a0641-addd-4ea8-a477-cdeb3861bc3b", + "link": "https://learn.microsoft.com/fabric/security/security-managed-private-endpoints-overview", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "配置託管專用終結點以訪問 Azure 服務", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5273,6 +6179,82 @@ "text": "配置託管專用終結點以使用託管 Azure IR 連接到資源", "waf": "安全" }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "Fabric 使用虛擬網路中的專用IP位址。終端節點允許您網路中的使用者使用私有連結通過私有IP位址與 Fabric 通信。", + "guid": "c14aea6e-65d8-4d9a-9aec-218e6436b063", + "link": "https://learn.microsoft.com/fabric/security/security-private-links-use", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "配置專用連結以訪問你自己的 Azure vnet 中的資源,即傳入 Fabric 環境的流量", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "當使用者進行身份驗證時,訪問是根據一組策略確定的,這些策略可能包括IP位址、位置和託管設備。", + "guid": "6cb45e57-9603-4324-adf8-cc23318da611", + "link": "https://learn.microsoft.com/fabric/security/security-conditional-access", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "如果使用者嘗試訪問您的 Fabric 環境,請配置 Microsoft Entra ID 條件訪問", + "training": "https://learn.microsoft.com/learn/paths/implement-network-security/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "在 Azure 中,服務標記是一組定義的 IP 位址,它作為一個組自動進行管理,以最大程度地降低網路安全規則更新或更改的複雜性。", + "guid": "70265f4b-b46a-4393-af70-317294797b15", + "link": "https://learn.microsoft.com/fabric/security/security-service-tags", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "您可以使用 Azure 服務標記來啟用與 Microsoft Fabric 之間的連接。", + "training": "https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "自選", + "guid": "78a219a4-6beb-4544-9502-4922634292bb", + "link": "https://learn.microsoft.com/fabric/security/fabric-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "您可以將 Fabric URL 加入到您的白名單中", + "training": "https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "自選", + "guid": "528537a5-4119-4bf8-b8f5-854287d9cdc1", + "link": "https://learn.microsoft.com/fabric/security/power-bi-allow-list-urls", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "您可以將 Power BI URL 新增到允許清單", + "training": "https://learn.microsoft.com/learn/modules/introduction-azure-virtual-wan/", + "waf": "安全" + }, + { + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "數據閘道允許您將 Azure 和其他資料服務連接到 Microsoft Fabric 和 Power Platform,以便安全地與數據源通信、執行查詢並將結果傳輸回服務。", + "guid": "56cc071a-e9b1-441a-a889-535e727897e7", + "link": "https://learn.microsoft.com/data-integration/gateway/service-gateway-install", + "service": "Microsoft Fabric", + "severity": "中等", + "text": "配置並使用本地數據閘道或 Vnet 資料閘道連接到本地或虛擬網路後面的源", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "通過使用 Azure 專用連結,可以通過專用終結點連接到 Azure 中的各種平臺即服務 (PaaS) 部署。專用終結點是特定虛擬網路和子網中的專用IP位址", + "guid": "b47a393a-0804-4272-a479-8b1578b219a4", + "link": "https://learn.microsoft.com/azure/data-factory/data-factory-private-link", + "service": "Azure Data Factory", + "severity": "中等", + "text": "配置專用連結以連接到客戶 Vnet 和數據工廠中的源", + "waf": "安全" + }, { "arm-service": "Microsoft.DataFactory/datafactories", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -5314,6 +6296,28 @@ "text": "在 Azure Key Vault 中存儲密碼和機密", "waf": "安全" }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "您可以將憑據或機密值存儲在 Azure Key Vault 中,並在管道執行期間使用它們以傳遞給您的活動。", + "guid": "6f4a1652-bddd-4ea8-a487-cdec4861bc3b", + "link": "https://learn.microsoft.com/azure/data-factory/how-to-use-azure-key-vault-secrets-pipeline-activities", + "service": "Azure Data Factory", + "severity": "中等", + "text": "在管道活動中使用 Azure Key Vault 機密", + "waf": "安全" + }, + { + "arm-service": "Microsoft.DataFactory/datafactories", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "您可以在具有自承載整合運行時的電腦上加密和儲存任何本地數據存儲(包含敏感資訊的連結服務)的憑據。", + "guid": "c14aeb7e-66e8-4d9a-9bec-218e6436b173", + "link": "https://learn.microsoft.com/azure/data-factory/encrypt-credentials-self-hosted-integration-runtime", + "service": "Azure Data Factory", + "severity": "中等", + "text": "使用 Azure 數據工廠中的 SHIR 數據儲存加密本地憑據", + "waf": "安全" + }, { "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", "guid": "6db55f57-9603-4334-adf9-cc23418db612", @@ -5578,6 +6582,17 @@ "text": "限制集群創建許可權。", "waf": "安全" }, + { + "arm-service": "Microsoft.Databricks/workspaces", + "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", + "description": "帳戶管理員可以配置名為 RestrictWorkspaceAdmins 的工作區設置,以限制工作區管理員僅將作業擁有者更改為自己,並將作業運行方式設置更改為他們具有服務主體使用者角色的服務主體。", + "guid": "6b57dfc6-5546-41e1-a3e3-453a3c863964", + "link": "https://learn.microsoft.com/azure/databricks/admin/workspace-settings/restrict-workspace-admins", + "service": "Azure Databricks", + "severity": "高", + "text": "限制工作區管理員", + "waf": "安全" + }, { "arm-service": "Microsoft.Databricks/workspaces", "checklist": "Use the 'Import latest checklist' button to get the latest version of a review checklist", @@ -6521,593 +7536,185 @@ "service": "AVS", "severity": "中等", "text": "如果使用 VPN 連接進行遷移,請相應地調整 MTU 大小。", - "waf": "性能" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "e614658d-d457-4e92-9139-b821102cad6e", - "service": "AVS", - "severity": "中等", - "text": "對於連接到 Azure(500Mbps 或更低)的低連接區域,請考慮部署 HCX WAN 優化設備", - "waf": "性能" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "ae01e6e8-43e5-42f4-922d-928c1b1cd521", - "service": "AVS", - "severity": "中等", - "text": "確保從本地裝置啟動遷移,而不是從雲端裝置啟動遷移(不要執行反向遷移)", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "e54a29a9-de39-4ac0-b7c2-8dc935657202", - "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", - "service": "AVS", - "severity": "中等", - "text": "使用 Azure Netapp Files 擴展 Azure VMware 解決方案的儲存時,請考慮將其用作 VMware 資料儲存庫,而不是直接附加到 VM 。", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "bff4564b-0d93-44a3-98b2-63e7dd60513a", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", - "service": "AVS", - "severity": "中等", - "text": "確保將專用 ExpressRoute 閘道用於外部資料儲存解決方案", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "3649906e-bad3-48ea-b53c-c7de1d8aaab3", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", - "service": "AVS", - "severity": "中等", - "text": "確保在用於外部數據存儲解決方案的 ExpressRoute 閘道上啟用了 FastPath", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "571549ab-8153-4d89-b89d-c7b33be2b1a2", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", - "service": "AVS", - "severity": "高", - "text": "如果使用延伸群集,請確保供應商支援所選的災難恢復解決方案", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "4c486b6d-8bdc-4059-acf7-5ee8a1309888", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", - "service": "AVS", - "severity": "高", - "text": "如果使用延伸群集,請確保提供的 SLA 符合您的要求", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "9579d66b-896d-471f-a6ca-7be9955d04c3", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", - "service": "AVS", - "severity": "高", - "text": "如果使用延伸群集,請確保兩條 ExpressRoute 線路都連接到連接中心。", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "c49d987c-b3d1-4325-aa12-4b6e4d0685ed", - "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", - "service": "AVS", - "severity": "高", - "text": "如果使用延伸群集,請確保兩條 ExpressRoute 線路都啟用了 GlobalReach。", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.AVS/privateClouds", - "checklist": "Azure VMware Solution Design Review", - "guid": "dce9793b-7bcd-4b3b-91eb-2ec14eea6e59", - "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", - "service": "AVS", - "severity": "高", - "text": "是否正確考慮了網站容災設置,並在需要時為您的業務進行了更改。", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "bb235c70-5e17-496f-bedf-a8a4c8cdec4c", - "link": "https://learn.microsoft.com/entra/identity-platform/msal-acquire-cache-tokens", - "service": "Entra", - "severity": "中等", - "text": "使用長期可撤銷令牌,緩存令牌並使用 Microsoft 標識庫以靜默方式獲取令牌", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "503547c1-447e-4c66-828a-71f0f1ce16dd", - "link": "https://learn.microsoft.com/azure/active-directory-b2c/deploy-custom-policies-devops", - "service": "AAD B2C", - "severity": "中等", - "text": "請確保登錄使用者流已備份並具有復原能力。請確保用於登錄使用者的代碼已備份且可恢復。與外部進程的彈性介面", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "3e3553a4-c873-4964-ab66-2d6c15f51296", - "link": "https://learn.microsoft.com/entra/architecture/resilient-end-user-experience#use-a-content-delivery-network", - "service": "AAD B2C", - "severity": "中等", - "text": "自訂品牌資產應託管在CDN上", - "waf": "性能" - }, - { - "checklist": "Identity Review Checklist", - "guid": "5398e6df-d237-4de1-93b1-6c21d79a9b64", - "link": "https://learn.microsoft.com/entra/identity/monitoring-health/reference-sla-performance", - "service": "AAD B2C", - "severity": "低", - "text": "擁有多個標識提供者(即使用您的 Microsoft、Google、Facebook 帳戶登錄)", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "604489a8-f42d-478e-98c0-7a73b22a4a57", - "link": "https://azure.microsoft.com/blog/setting-up-active-directory-for-a-disaster-recovery-environment-2/", - "service": "Windows AD", - "severity": "中等", - "text": "遵循 VM 規則,實現 VM 級別的高可用性(高級磁碟,一個區域中的兩個或更多磁碟,位於不同的可用性區域)", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "e7a8dd4a-30e3-47c3-b297-11b2362ceee0", - "link": "https://azure.microsoft.com/blog/setting-up-active-directory-for-a-disaster-recovery-environment-2/", - "service": "Windows AD", - "severity": "中等", - "text": "不要複製!複製可能會產生目錄同步問題", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "79b598de-fc59-472c-b4cd-21b078036f5e", - "link": "https://azure.microsoft.com/blog/setting-up-active-directory-for-a-disaster-recovery-environment-2/", - "service": "Windows AD", - "severity": "中等", - "text": "對多區域具有主動-主動", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "6b4bfd3d-5035-447c-8447-ec66128a71f0", - "link": "https://learn.microsoft.com/entra/identity/domain-services/tutorial-perform-disaster-recovery-drill", - "service": "Entra", - "severity": "中等", - "text": "將 Azure AD 域服務標記添加到其他區域和位置", - "waf": "可靠性" - }, - { - "checklist": "Identity Review Checklist", - "guid": "f1ce16dd-3f1d-45e8-92e4-2e3611cc58b4", - "link": "https://learn.microsoft.com/entra/identity/domain-services/tutorial-perform-disaster-recovery-drill", - "service": "Entra", - "severity": "中等", - "text": "將副本集用於DR", - "waf": "可靠性" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "應用與存儲相關的 Microsoft 雲安全基準中的指導", - "guid": "d237de14-3b16-4c21-b7aa-9b64604489a8", - "link": "https://learn.microsoft.com/security/benchmark/azure/baselines/storage-security-baseline", - "service": "Azure Storage", - "severity": "中等", - "text": "請考慮「存儲的 Azure 安全基線”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "默認情況下,Azure 儲存具有公共IP位址,並且可通過Internet訪問。專用終結點允許僅向需要訪問的 Azure 計算資源安全地公開 Azure 存儲,從而消除對公共 Internet 的暴露", - "guid": "f42d78e7-9d17-4a73-a22a-5a67e7a8ed4b", - "link": "https://learn.microsoft.com/azure/storage/common/storage-private-endpoints", - "service": "Azure Storage", - "severity": "高", - "text": "考慮將專用終結點用於 Azure 存儲", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "新創建的存儲帳戶是使用ARM部署模型創建的,因此 RBAC、審核等都已啟用。確保訂閱中沒有具有經典部署模型的舊存儲帳戶", - "guid": "30e37c3e-2971-41b2-963c-eee079b598de", - "link": "https://learn.microsoft.com/azure/virtual-machines/migration-classic-resource-manager-overview#migration-of-storage-accounts", - "service": "Azure Storage", - "severity": "中等", - "text": "確保較舊的存儲帳戶未使用“經典部署模型”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "利用 Microsoft Defender 瞭解可疑活動和錯誤配置。", - "guid": "fc5972cd-4cd2-41b0-a803-7f5e6b4bfd3d", - "link": "https://learn.microsoft.com/azure/storage/common/azure-defender-storage-configure", - "service": "Azure Storage", - "severity": "高", - "text": "為所有存儲帳戶啟用 Microsoft DefenderEnable Defender for all of your storage accounts", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "軟刪除機制允許恢復意外刪除的 Blob。", - "guid": "503547c1-447e-4c66-828a-7100f1ce16dd", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-overview", - "service": "Azure Storage", - "severity": "中等", - "text": "為 blob 啟用“軟刪除”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "請考慮有選擇地禁用某些 blob 容器的「軟刪除」 例如,如果應用程式必須確保立即刪除已刪除的資訊,例如出於機密性、隱私或合規性原因。", - "guid": "3f1d5e87-2e52-4e36-81cc-58b4a4b1510e", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-blob-enable", - "service": "Azure Storage", - "severity": "中等", - "text": "禁用 blob 的“軟刪除”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "容器的軟刪除使你能夠在刪除容器后恢復容器,例如從意外刪除操作中恢復。", - "guid": "43a58a9c-2289-4c3d-9b57-d0c655462f2a", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-overview", - "service": "Azure Storage", - "severity": "高", - "text": "為容器啟用“軟刪除”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "請考慮有選擇地禁用某些 blob 容器的「軟刪除」 例如,如果應用程式必須確保立即刪除已刪除的資訊,例如出於機密性、隱私或合規性原因。", - "guid": "3e3453a3-c863-4964-ab65-2d6c15f51296", - "link": "https://learn.microsoft.com/azure/storage/blobs/soft-delete-container-enable", - "service": "Azure Storage", - "severity": "中等", - "text": "禁用容器的“軟刪除”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "通過強制使用者在刪除之前先刪除刪除鎖,防止意外刪除存儲帳戶", - "guid": "5398e6de-d227-4dd1-92b0-6c21d7999a64", - "link": "https://learn.microsoft.com/azure/storage/common/lock-account-resource", - "service": "Azure Storage", - "severity": "高", - "text": "在存儲帳戶上啟用資源鎖", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "請考慮對 blob 使用“合法保留”或“基于時間的保留”策略,這樣就無法刪除 blob、容器或存儲帳戶。請注意,「不可能」實際上意味著「不可能」;存儲帳戶包含不可變 blob 後,「擺脫」該存儲帳戶的唯一方法是取消 Azure 訂閱。", - "guid": "6f4389a8-f42c-478e-98c0-6a73a22a4956", - "link": "https://learn.microsoft.com/azure/storage/blobs/immutable-storage-overview", - "service": "Azure Storage", - "severity": "高", - "text": "考慮不可變的 blob", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "請考慮禁用對存儲帳戶的未受保護的 HTTP/80 訪問,以便對所有數據傳輸進行加密、完整性保護,並對伺服器進行身份驗證。", - "guid": "e7a8dc4a-20e2-47c3-b297-11b1352beee0", - "link": "https://learn.microsoft.com/azure/storage/common/storage-require-secure-transfer", - "service": "Azure Storage", - "severity": "高", - "text": "需要 HTTPS,即在儲存帳戶上禁用埠 80", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "在儲存帳戶上配置自定義域(主機名)時,請檢查是否需要 TLS/HTTPS;如果是這樣,可能需要將 Azure CDN 放在存儲帳戶的前面。", - "guid": "79b588de-fc49-472c-b3cd-21bf77036e5e", - "link": "https://learn.microsoft.com/azure/storage/blobs/storage-custom-domain-name", - "service": "Azure Storage", - "severity": "高", - "text": "強制實施 HTTPS(禁用 HTTP)時,請檢查是否未對儲存帳戶使用自定義域 (CNAME)。", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "當用戶端使用SAS令牌訪問 blob 資料時,要求使用 HTTPS 有助於將憑據丟失的風險降至最低。", - "guid": "6b4bed3d-5035-447c-8347-dc56028a71ff", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview", - "service": "Azure Storage", - "severity": "中等", - "text": "將共享訪問簽名 (SAS) 令牌限製為僅 HTTPS 連接", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "在可能的情況下,AAD 令牌應優先於共用訪問簽名", - "guid": "e1ce15dd-3f0d-45e7-92d4-1e3611cc57b4", - "link": "https://learn.microsoft.com/azure/storage/common/authorize-data-access", - "service": "Azure Storage", - "severity": "高", - "text": "使用 Azure Active Directory (Azure AD) 令牌進行 blob 訪問", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "將角色分配給使用者、組或應用程式時,請僅向該安全主體授予他們執行任務所需的許可權。限制對資源的訪問有助於防止無意和惡意濫用數據。", - "guid": "a4b1410d-4395-48a8-a228-9b3d6b57cfc6", - "service": "Azure Storage", - "severity": "中等", - "text": "IaM 許可權中的最低特權", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "使用者委派 SAS 使用 Azure Active Directory (Azure AD) 憑據以及為 SAS 指定的許可權進行保護。使用者委派 SAS 在範圍和功能方面類似於服務 SAS,但比服務 SAS 具有安全優勢。", - "guid": "55461e1a-3e34-453a-9c86-39648b652d6c", - "link": "https://learn.microsoft.com/azure/storage/common/storage-sas-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json#best-practices-when-using-sas", - "service": "Azure Storage", - "severity": "高", - "text": "使用 SAS 時,首選「使用者委派 SAS」,而不是基於存儲帳戶密鑰的 SAS。", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "存儲帳戶金鑰(“共用金鑰”)幾乎沒有審核功能。雖然可以監控誰/何時獲取密鑰副本,但一旦密鑰掌握在多個人手中,就不可能將使用方式歸因於特定使用者。僅依靠 AAD 身份驗證可以更輕鬆地將存儲存取許可權綁定到使用者。", - "guid": "15f51296-5398-4e6d-bd22-7dd142b06c21", - "link": "https://learn.microsoft.com/rest/api/storageservices/authorize-with-shared-key", - "service": "Azure Storage", - "severity": "高", - "text": "請考慮禁用存儲帳戶密鑰,以便僅支援 AAD 訪問(和使用者委派 SAS)。", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "使用活動日誌數據來標識查看或更改存儲帳戶安全性的“時間”、“人員”、“內容”和“方式”(即存儲帳戶密鑰、訪問策略等)。", - "guid": "d7999a64-6f43-489a-af42-c78e78c06a73", - "link": "https://learn.microsoft.com/azure/storage/blobs/blob-storage-monitoring-scenarios#audit-account-activity", - "service": "Azure Storage", - "severity": "高", - "text": "請考慮使用 Azure Monitor 審核存儲帳戶上的控制平面操作", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "通過金鑰過期策略,您可以設置帳戶訪問金鑰輪換的提醒。如果指定的時間間隔已過且鍵尚未旋轉,則會顯示提醒。", - "guid": "a22a4956-e7a8-4dc4-a20e-27c3e29711b1", - "link": "https://learn.microsoft.com/azure/storage/common/storage-account-keys-manage?tabs=azure-portal#create-a-key-expiration-policy", - "service": "Azure Storage", - "severity": "中等", - "text": "使用存儲帳戶密鑰時,請考慮啟用“金鑰過期策略”", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS 過期策略指定 SAS 有效的建議時間間隔。SAS 過期策略適用於服務 SAS 或帳戶 SAS。當使用者生成的服務 SAS 或帳戶 SAS 的有效期間隔大於建議的時間間隔時,他們會看到警告。", - "guid": "352beee0-79b5-488d-bfc4-972cd3cd21bf", - "link": "https://learn.microsoft.com/azure/storage/common/sas-expiration-policy", - "service": "Azure Storage", - "severity": "中等", - "text": "考慮配置 SAS 過期策略", - "waf": "安全" - }, - { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "存儲存取策略提供了撤銷服務 SAS 許可權的選項,而無需重新生成儲存帳戶密鑰。", - "guid": "77036e5e-6b4b-4ed3-b503-547c1347dc56", - "link": "https://learn.microsoft.com/rest/api/storageservices/define-stored-access-policy", - "service": "Azure Storage", - "severity": "中等", - "text": "考慮將 SAS 連結到儲存存取策略", - "waf": "安全" + "waf": "性能" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "028a71ff-e1ce-415d-b3f0-d5e772d41e36", - "link": "https://microsoft.github.io/code-with-engineering-playbook/continuous-integration/dev-sec-ops/secret-management/recipes/detect-secrets-ado/", - "service": "Azure Storage", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "e614658d-d457-4e92-9139-b821102cad6e", + "service": "AVS", "severity": "中等", - "text": "請考慮配置應用程式的原始程式碼儲存庫,以檢測簽入的連接字串和存儲帳戶密鑰。", - "waf": "安全" + "text": "對於連接到 Azure(500Mbps 或更低)的低連接區域,請考慮部署 HCX WAN 優化設備", + "waf": "性能" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "理想情況下,應用程式應使用託管標識向 Azure 儲存進行身份驗證。如果無法做到這一點,請考慮在 Azure KeyVault 或等效服務中使用存儲憑據(連接字串、存儲帳戶密鑰、SAS、服務主體憑據)。", - "guid": "11cc57b4-a4b1-4410-b439-58a8c2289b3d", - "link": "https://learn.microsoft.com/azure/architecture/framework/security/design-storage-keys", - "service": "Azure Storage", - "severity": "高", - "text": "請考慮將連接字串儲存在 Azure KeyVault 中(在無法實現託管標識的情況下)", - "waf": "安全" + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "ae01e6e8-43e5-42f4-922d-928c1b1cd521", + "service": "AVS", + "severity": "中等", + "text": "確保從本地裝置啟動遷移,而不是從雲端裝置啟動遷移(不要執行反向遷移)", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "在臨時 SAS 服務 SAS 或帳戶 SAS 上使用近期過期時間。這樣,即使 SAS 遭到入侵,它也只能在很短的時間內有效。如果無法引用存儲訪問策略,則此做法尤為重要。近期過期時間還通過限制可上傳到 blob 的時間來限制可寫入 blob 的數據量。", - "guid": "27138b82-1102-4cac-9eae-01e6e842e52f", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", - "severity": "高", - "text": "爭取縮短臨時 SAS 的有效期", - "waf": "安全" + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "e54a29a9-de39-4ac0-b7c2-8dc935657202", + "link": "https://learn.microsoft.com/azure/web-application-firewall/afds/waf-front-door-policy-settings", + "service": "AVS", + "severity": "中等", + "text": "使用 Azure Netapp Files 擴展 Azure VMware 解決方案的儲存時,請考慮將其用作 VMware 資料儲存庫,而不是直接附加到 VM 。", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "創建 SAS 時,請盡可能具體和嚴格。首選單個資源和操作的 SAS,而不是提供更廣泛訪問許可權的 SAS。", - "guid": "4721d928-c1b1-4cd5-81e5-4a29a9de399c", - "link": "https://learn.microsoft.com/rest/api/storageservices/delegate-access-with-shared-access-signature", - "service": "Azure Storage", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "bff4564b-0d93-44a3-98b2-63e7dd60513a", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#avoid-combining-traffic-manager-and-front-door", + "service": "AVS", "severity": "中等", - "text": "將窄範圍應用於SAS", - "waf": "安全" + "text": "確保將專用 ExpressRoute 閘道用於外部資料儲存解決方案", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS 可以包含用戶端 IP 位址或位址範圍有權使用 SAS 請求資源的參數。", - "guid": "fd7b28dc-9355-4562-82bf-e4564b0d834a", - "link": "https://learn.microsoft.com/rest/api/storageservices/create-account-sas", - "service": "Azure Storage", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "3649906e-bad3-48ea-b53c-c7de1d8aaab3", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-the-same-domain-name-on-front-door-and-your-origin", + "service": "AVS", "severity": "中等", - "text": "盡可能考慮將SAS的範圍限定為特定的用戶端IP位址", - "waf": "安全" + "text": "確保在用於外部數據存儲解決方案的 ExpressRoute 閘道上啟用了 FastPath", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "SAS 無法限制用戶端上傳的數據量;考慮到存儲量隨時間變化的定價模型,驗證用戶端是否惡意上傳了大量內容可能是有意義的。", - "guid": "348b263e-6dd6-4051-8a36-498f6dbad38e", - "service": "Azure Storage", - "severity": "低", - "text": "請考慮在用戶端使用SAS上傳檔后檢查上傳的數據。", - "waf": "安全" + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "571549ab-8153-4d89-b89d-c7b33be2b1a2", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#disable-health-probes-when-theres-only-one-origin-in-an-origin-group", + "service": "AVS", + "severity": "高", + "text": "如果使用延伸群集,請確保供應商支援所選的災難恢復解決方案", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "使用「本地使用者帳戶」通過 SFTP 訪問 Blob 儲存時,“通常”RBAC 控制不適用。通過 NFS 或 REST 進行的 Blob 訪問可能比 SFTP 訪問更嚴格。遺憾的是,截至 2023 年初,本地使用者是 SFTP 端點當前支援的唯一身份管理形式", - "guid": "ad53cc7c-e1d7-4aaa-a357-1449ab8053d8", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-support#sftp-permission-model", - "service": "Azure Storage", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "4c486b6d-8bdc-4059-acf7-5ee8a1309888", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#select-good-health-probe-endpoints", + "service": "AVS", "severity": "高", - "text": "SFTP:限制 SFTP 訪問的「本地使用者」數量,並審核一段時間內是否需要訪問。", - "waf": "安全" + "text": "如果使用延伸群集,請確保提供的 SLA 符合您的要求", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "9f89dc7b-33be-42a1-a27f-7b9e91be1f38", - "link": "https://learn.microsoft.com/azure/storage/blobs/secure-file-transfer-protocol-known-issues#authentication-and-authorization", - "service": "Azure Storage", - "severity": "中等", - "text": "SFTP:SFTP 端點不支持類似 POSIX 的 ACL。", - "waf": "安全" + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "9579d66b-896d-471f-a6ca-7be9955d04c3", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-head-health-probes", + "service": "AVS", + "severity": "高", + "text": "如果使用延伸群集,請確保兩條 ExpressRoute 線路都連接到連接中心。", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "存儲支援 CORS(跨域資源分享),即一種 HTTP 功能,使來自不同域的 Web 應用程式能夠放寬同源策略。啟用 CORS 時,請將 CorsRules 保留為最低許可權。", - "guid": "cef39812-bd46-43cb-aac8-ac199ebb91a3", - "link": "https://learn.microsoft.com/rest/api/storageservices/cross-origin-resource-sharing--cors--support-for-the-azure-storage-services", - "service": "Azure Storage", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "c49d987c-b3d1-4325-aa12-4b6e4d0685ed", + "link": "https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity", + "service": "AVS", "severity": "高", - "text": "避免過於寬泛的 CORS 策略", - "waf": "安全" + "text": "如果使用延伸群集,請確保兩條 ExpressRoute 線路都啟用了 GlobalReach。", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "靜態數據始終在伺服器端加密,此外也可能在用戶端加密。伺服器端加密可能使用平臺管理的金鑰(預設)或客戶管理的金鑰進行。用戶端加密可以通過讓用戶端按 blob 向 Azure 儲存提供加密/解密金鑰,或者完全在用戶端處理加密來實現。因此,完全不依賴 Azure 存儲來保證機密性。", - "guid": "3d90cae2-cc88-4137-86f7-c0cbafe61464", - "link": "https://learn.microsoft.com/azure/storage/common/storage-service-encryption", - "service": "Azure Storage", + "arm-service": "Microsoft.AVS/privateClouds", + "checklist": "Azure VMware Solution Design Review", + "guid": "dce9793b-7bcd-4b3b-91eb-2ec14eea6e59", + "link": "https://learn.microsoft.com/azure/frontdoor/best-practices#use-managed-tls-certificates", + "service": "AVS", "severity": "高", - "text": "確定應如何加密靜態數據。了解數據的線程模型。", - "waf": "安全" + "text": "是否正確考慮了網站容災設置,並在需要時為您的業務進行了更改。", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "8dd457e9-2713-48b8-8110-2cac6eae01e6", - "link": "https://learn.microsoft.com/azure/storage/common/customer-managed-keys-overview?toc=%2Fazure%2Fstorage%2Fblobs%2Ftoc.json&bc=%2Fazure%2Fstorage%2Fblobs%2Fbreadcrumb%2Ftoc.json", - "service": "Azure Storage", + "checklist": "Identity Review Checklist", + "guid": "bb235c70-5e17-496f-bedf-a8a4c8cdec4c", + "link": "https://learn.microsoft.com/entra/identity-platform/msal-acquire-cache-tokens", + "service": "Entra", "severity": "中等", - "text": "確定應使用哪種/是否應使用平臺加密。", - "waf": "安全" + "text": "使用長期可撤銷令牌,緩存令牌並使用 Microsoft 標識庫以靜默方式獲取令牌", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "guid": "e842e52f-4721-4d92-ac1b-1cd521e54a29", - "link": "https://learn.microsoft.com/azure/storage/blobs/encryption-customer-provided-keys", - "service": "Azure Storage", + "checklist": "Identity Review Checklist", + "guid": "503547c1-447e-4c66-828a-71f0f1ce16dd", + "link": "https://learn.microsoft.com/azure/active-directory-b2c/deploy-custom-policies-devops", + "service": "AAD B2C", "severity": "中等", - "text": "確定應使用哪種/是否應使用用戶端加密。", - "waf": "安全" + "text": "請確保登錄使用者流已備份並具有復原能力。請確保用於登錄使用者的代碼已備份且可恢復。與外部進程的彈性介面", + "waf": "可靠性" }, { - "arm-service": "Microsoft.Storage/storageAccounts", - "checklist": "Azure Blob Storage Review", - "description": "利用 Resource Graph 資源管理器(資源 | where type == 'microsoft.storage/storageaccounts' | where properties['allowBlobPublicAccess'] == true)查找允許匿名 blob 訪問的存儲帳戶。", - "guid": "659ae558-b937-4d49-a5e1-112dbd7ba012", - "link": "https://learn.microsoft.com/azure/storage/blobs/anonymous-read-access-configure?tabs=portal#allow-or-disallow-public-read-access-for-a-storage-account", - "service": "Azure Storage", - "severity": "高", - "text": "考慮是否需要公共 blob 訪問,或者是否可以對某些存儲帳戶禁用公共 blob 訪問。", - "waf": "安全" + "checklist": "Identity Review Checklist", + "guid": "3e3553a4-c873-4964-ab66-2d6c15f51296", + "link": "https://learn.microsoft.com/entra/architecture/resilient-end-user-experience#use-a-content-delivery-network", + "service": "AAD B2C", + "severity": "中等", + "text": "自訂品牌資產應託管在CDN上", + "waf": "性能" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "65285269-440b-44be-9d3e-0844276d4bdc", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-zone-redundancy", - "service": "Redis", - "severity": "高", - "text": "為 Azure Cache for Redis 啟用區域冗餘。Azure Cache for Redis 支持高級層和企業層中的區域冗餘配置。區域冗餘緩存可以將其節點放置在同一區域的不同 Azure 可用性區域中。它消除了作為單點故障的數據中心或可用區中斷,並提高了緩存的整體可用性。", + "checklist": "Identity Review Checklist", + "guid": "5398e6df-d237-4de1-93b1-6c21d79a9b64", + "link": "https://learn.microsoft.com/entra/identity/monitoring-health/reference-sla-performance", + "service": "AAD B2C", + "severity": "低", + "text": "擁有多個標識提供者(即使用您的 Microsoft、Google、Facebook 帳戶登錄)", "waf": "可靠性" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "bc178bdc-5a06-4ca7-8443-51e19dd34429", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#persistence", - "service": "Redis", + "checklist": "Identity Review Checklist", + "guid": "604489a8-f42d-478e-98c0-7a73b22a4a57", + "link": "https://azure.microsoft.com/blog/setting-up-active-directory-for-a-disaster-recovery-environment-2/", + "service": "Windows AD", "severity": "中等", - "text": "為 Azure Cache for Redis 實例配置數據持久性。由於緩存數據存儲在記憶體中,因此多個節點的罕見和計劃外故障可能會導致所有數據被丟棄。為了避免完全丟失數據,Redis 持久性允許您定期拍攝記憶體中數據的快照,並將其存儲到存儲帳戶中。", + "text": "遵循 VM 規則,實現 VM 級別的高可用性(高級磁碟,一個區域中的兩個或更多磁碟,位於不同的可用性區域)", "waf": "可靠性" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "eb722823-7a15-41c5-ab4e-4f1814387e5c", - "link": "https://learn.microsoft.com/en-us/azure/azure-cache-for-redis/cache-high-availability#storage-account-for-persistence", - "service": "Redis", + "checklist": "Identity Review Checklist", + "guid": "e7a8dd4a-30e3-47c3-b297-11b2362ceee0", + "link": "https://azure.microsoft.com/blog/setting-up-active-directory-for-a-disaster-recovery-environment-2/", + "service": "Windows AD", "severity": "中等", - "text": "使用異地冗餘存儲帳戶保留 Azure Cache for Redis 數據,或在異地冗餘不可用的情況下使用區域冗餘", + "text": "不要複製!複製可能會產生目錄同步問題", "waf": "可靠性" }, { - "arm-service": "microsoft.cache/redis", - "checklist": "Redis Resiliency checklist", - "guid": "a8c26c9b-32ab-45bd-bc69-98a135e33789", - "link": "https://learn.microsoft.com/azure/azure-cache-for-redis/cache-how-to-geo-replication", - "service": "Redis", + "checklist": "Identity Review Checklist", + "guid": "79b598de-fc59-472c-b4cd-21b078036f5e", + "link": "https://azure.microsoft.com/blog/setting-up-active-directory-for-a-disaster-recovery-environment-2/", + "service": "Windows AD", + "severity": "中等", + "text": "對多區域具有主動-主動", + "waf": "可靠性" + }, + { + "checklist": "Identity Review Checklist", + "guid": "6b4bfd3d-5035-447c-8447-ec66128a71f0", + "link": "https://learn.microsoft.com/entra/identity/domain-services/tutorial-perform-disaster-recovery-drill", + "service": "Entra", + "severity": "中等", + "text": "將 Azure AD 域服務標記添加到其他區域和位置", + "waf": "可靠性" + }, + { + "checklist": "Identity Review Checklist", + "guid": "f1ce16dd-3f1d-45e8-92e4-2e3611cc58b4", + "link": "https://learn.microsoft.com/entra/identity/domain-services/tutorial-perform-disaster-recovery-drill", + "service": "Entra", "severity": "中等", - "text": "為高級 Azure Cache for Redis 實例配置被動異地複製。異地複製是一種用於連結兩個或多個 Azure Cache for Redis 實例的機制,通常跨越兩個 Azure 區域。異地複製主要用於跨區域災難恢復。兩個高級層緩存實例通過異地複製進行連接,從而提供對主緩存的讀取和寫入,並將數據複製到輔助緩存。", + "text": "將副本集用於DR", "waf": "可靠性" }, { @@ -10670,7 +11277,7 @@ ], "metadata": { "name": "WAF checklist", - "timestamp": "October 21, 2024" + "timestamp": "October 23, 2024" }, "severities": [ { diff --git a/spreadsheet/macrofree/acr_checklist.en.xlsx b/spreadsheet/macrofree/acr_checklist.en.xlsx new file mode 100644 index 00000000..c4a34d4c Binary files /dev/null and b/spreadsheet/macrofree/acr_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/acr_checklist.es.xlsx b/spreadsheet/macrofree/acr_checklist.es.xlsx new file mode 100644 index 00000000..967922ee Binary files /dev/null and b/spreadsheet/macrofree/acr_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/acr_checklist.ja.xlsx b/spreadsheet/macrofree/acr_checklist.ja.xlsx new file mode 100644 index 00000000..478cdce8 Binary files /dev/null and b/spreadsheet/macrofree/acr_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/acr_checklist.ko.xlsx b/spreadsheet/macrofree/acr_checklist.ko.xlsx new file mode 100644 index 00000000..0217c38d Binary files /dev/null and b/spreadsheet/macrofree/acr_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/acr_checklist.pt.xlsx b/spreadsheet/macrofree/acr_checklist.pt.xlsx new file mode 100644 index 00000000..5fdd08aa Binary files /dev/null and b/spreadsheet/macrofree/acr_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/acr_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/acr_checklist.zh-Hant.xlsx new file mode 100644 index 00000000..6cb33b43 Binary files /dev/null and b/spreadsheet/macrofree/acr_checklist.zh-Hant.xlsx differ diff --git a/spreadsheet/macrofree/blob_storage_checklist.es.xlsx b/spreadsheet/macrofree/blob_storage_checklist.es.xlsx new file mode 100644 index 00000000..61e07a27 Binary files /dev/null and b/spreadsheet/macrofree/blob_storage_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/blob_storage_checklist.ja.xlsx b/spreadsheet/macrofree/blob_storage_checklist.ja.xlsx new file mode 100644 index 00000000..e36fd0c7 Binary files /dev/null and b/spreadsheet/macrofree/blob_storage_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/blob_storage_checklist.ko.xlsx b/spreadsheet/macrofree/blob_storage_checklist.ko.xlsx new file mode 100644 index 00000000..9ac84cbb Binary files /dev/null and b/spreadsheet/macrofree/blob_storage_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/blob_storage_checklist.pt.xlsx b/spreadsheet/macrofree/blob_storage_checklist.pt.xlsx new file mode 100644 index 00000000..7aa6ee7b Binary files /dev/null and b/spreadsheet/macrofree/blob_storage_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/blob_storage_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/blob_storage_checklist.zh-Hant.xlsx new file mode 100644 index 00000000..86ed6a46 Binary files /dev/null and b/spreadsheet/macrofree/blob_storage_checklist.zh-Hant.xlsx differ diff --git a/spreadsheet/macrofree/checklist.en.master.xlsx b/spreadsheet/macrofree/checklist.en.master.xlsx index aa01a702..2d046ce5 100644 Binary files a/spreadsheet/macrofree/checklist.en.master.xlsx and b/spreadsheet/macrofree/checklist.en.master.xlsx differ diff --git a/spreadsheet/macrofree/datasecurity_checklist.en.xlsx b/spreadsheet/macrofree/datasecurity_checklist.en.xlsx index 10dc39cc..3a587342 100644 Binary files a/spreadsheet/macrofree/datasecurity_checklist.en.xlsx and b/spreadsheet/macrofree/datasecurity_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/datasecurity_checklist.es.xlsx b/spreadsheet/macrofree/datasecurity_checklist.es.xlsx index 67f96549..234611bc 100644 Binary files a/spreadsheet/macrofree/datasecurity_checklist.es.xlsx and b/spreadsheet/macrofree/datasecurity_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/datasecurity_checklist.ja.xlsx b/spreadsheet/macrofree/datasecurity_checklist.ja.xlsx index d09315a2..01262e50 100644 Binary files a/spreadsheet/macrofree/datasecurity_checklist.ja.xlsx and b/spreadsheet/macrofree/datasecurity_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/datasecurity_checklist.ko.xlsx b/spreadsheet/macrofree/datasecurity_checklist.ko.xlsx index 8a9b63e5..7911bdab 100644 Binary files a/spreadsheet/macrofree/datasecurity_checklist.ko.xlsx and b/spreadsheet/macrofree/datasecurity_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/datasecurity_checklist.pt.xlsx b/spreadsheet/macrofree/datasecurity_checklist.pt.xlsx index 8bead3ec..49fdf1d3 100644 Binary files a/spreadsheet/macrofree/datasecurity_checklist.pt.xlsx and b/spreadsheet/macrofree/datasecurity_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/datasecurity_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/datasecurity_checklist.zh-Hant.xlsx index 4e4ac60f..39b976f5 100644 Binary files a/spreadsheet/macrofree/datasecurity_checklist.zh-Hant.xlsx and b/spreadsheet/macrofree/datasecurity_checklist.zh-Hant.xlsx differ diff --git a/spreadsheet/macrofree/redis_checklist.en.xlsx b/spreadsheet/macrofree/redis_checklist.en.xlsx new file mode 100644 index 00000000..ed7e59ea Binary files /dev/null and b/spreadsheet/macrofree/redis_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/redis_checklist.es.xlsx b/spreadsheet/macrofree/redis_checklist.es.xlsx new file mode 100644 index 00000000..9b8d4a5b Binary files /dev/null and b/spreadsheet/macrofree/redis_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/redis_checklist.ja.xlsx b/spreadsheet/macrofree/redis_checklist.ja.xlsx new file mode 100644 index 00000000..c7b17b20 Binary files /dev/null and b/spreadsheet/macrofree/redis_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/redis_checklist.ko.xlsx b/spreadsheet/macrofree/redis_checklist.ko.xlsx new file mode 100644 index 00000000..92fc9b8c Binary files /dev/null and b/spreadsheet/macrofree/redis_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/redis_checklist.pt.xlsx b/spreadsheet/macrofree/redis_checklist.pt.xlsx new file mode 100644 index 00000000..04f0b47e Binary files /dev/null and b/spreadsheet/macrofree/redis_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/redis_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/redis_checklist.zh-Hant.xlsx new file mode 100644 index 00000000..b0143b9d Binary files /dev/null and b/spreadsheet/macrofree/redis_checklist.zh-Hant.xlsx differ diff --git a/spreadsheet/macrofree/sqldb_checklist.en.xlsx b/spreadsheet/macrofree/sqldb_checklist.en.xlsx new file mode 100644 index 00000000..eb7f1e29 Binary files /dev/null and b/spreadsheet/macrofree/sqldb_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/sqldb_checklist.es.xlsx b/spreadsheet/macrofree/sqldb_checklist.es.xlsx new file mode 100644 index 00000000..69f600e5 Binary files /dev/null and b/spreadsheet/macrofree/sqldb_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/sqldb_checklist.ja.xlsx b/spreadsheet/macrofree/sqldb_checklist.ja.xlsx new file mode 100644 index 00000000..43e62da9 Binary files /dev/null and b/spreadsheet/macrofree/sqldb_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/sqldb_checklist.ko.xlsx b/spreadsheet/macrofree/sqldb_checklist.ko.xlsx new file mode 100644 index 00000000..18ade4c5 Binary files /dev/null and b/spreadsheet/macrofree/sqldb_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/sqldb_checklist.pt.xlsx b/spreadsheet/macrofree/sqldb_checklist.pt.xlsx new file mode 100644 index 00000000..3c3efd15 Binary files /dev/null and b/spreadsheet/macrofree/sqldb_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/sqldb_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/sqldb_checklist.zh-Hant.xlsx new file mode 100644 index 00000000..37a4934c Binary files /dev/null and b/spreadsheet/macrofree/sqldb_checklist.zh-Hant.xlsx differ diff --git a/spreadsheet/macrofree/streamanalytics_checklist.en.xlsx b/spreadsheet/macrofree/streamanalytics_checklist.en.xlsx new file mode 100644 index 00000000..977a0863 Binary files /dev/null and b/spreadsheet/macrofree/streamanalytics_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/streamanalytics_checklist.es.xlsx b/spreadsheet/macrofree/streamanalytics_checklist.es.xlsx new file mode 100644 index 00000000..2c2a4f03 Binary files /dev/null and b/spreadsheet/macrofree/streamanalytics_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/streamanalytics_checklist.ja.xlsx b/spreadsheet/macrofree/streamanalytics_checklist.ja.xlsx new file mode 100644 index 00000000..efbed62b Binary files /dev/null and b/spreadsheet/macrofree/streamanalytics_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/streamanalytics_checklist.ko.xlsx b/spreadsheet/macrofree/streamanalytics_checklist.ko.xlsx new file mode 100644 index 00000000..2ec17989 Binary files /dev/null and b/spreadsheet/macrofree/streamanalytics_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/streamanalytics_checklist.pt.xlsx b/spreadsheet/macrofree/streamanalytics_checklist.pt.xlsx new file mode 100644 index 00000000..f809b07a Binary files /dev/null and b/spreadsheet/macrofree/streamanalytics_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/streamanalytics_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/streamanalytics_checklist.zh-Hant.xlsx new file mode 100644 index 00000000..76d1979c Binary files /dev/null and b/spreadsheet/macrofree/streamanalytics_checklist.zh-Hant.xlsx differ diff --git a/spreadsheet/macrofree/waf_checklist.en.xlsx b/spreadsheet/macrofree/waf_checklist.en.xlsx index 5eb0345f..49fac525 100644 Binary files a/spreadsheet/macrofree/waf_checklist.en.xlsx and b/spreadsheet/macrofree/waf_checklist.en.xlsx differ diff --git a/spreadsheet/macrofree/waf_checklist.es.xlsx b/spreadsheet/macrofree/waf_checklist.es.xlsx index 92440040..13272681 100644 Binary files a/spreadsheet/macrofree/waf_checklist.es.xlsx and b/spreadsheet/macrofree/waf_checklist.es.xlsx differ diff --git a/spreadsheet/macrofree/waf_checklist.ja.xlsx b/spreadsheet/macrofree/waf_checklist.ja.xlsx index 538306c9..86ce91a3 100644 Binary files a/spreadsheet/macrofree/waf_checklist.ja.xlsx and b/spreadsheet/macrofree/waf_checklist.ja.xlsx differ diff --git a/spreadsheet/macrofree/waf_checklist.ko.xlsx b/spreadsheet/macrofree/waf_checklist.ko.xlsx index 261c714b..f325ac7c 100644 Binary files a/spreadsheet/macrofree/waf_checklist.ko.xlsx and b/spreadsheet/macrofree/waf_checklist.ko.xlsx differ diff --git a/spreadsheet/macrofree/waf_checklist.pt.xlsx b/spreadsheet/macrofree/waf_checklist.pt.xlsx index b7b49957..19174cbc 100644 Binary files a/spreadsheet/macrofree/waf_checklist.pt.xlsx and b/spreadsheet/macrofree/waf_checklist.pt.xlsx differ diff --git a/spreadsheet/macrofree/waf_checklist.zh-Hant.xlsx b/spreadsheet/macrofree/waf_checklist.zh-Hant.xlsx index 291ef9f0..26f626fe 100644 Binary files a/spreadsheet/macrofree/waf_checklist.zh-Hant.xlsx and b/spreadsheet/macrofree/waf_checklist.zh-Hant.xlsx differ diff --git a/workbooks/acr_checklist.en_counters_workbook.json b/workbooks/acr_checklist.en_counters_workbook.json new file mode 100644 index 00000000..c5814473 --- /dev/null +++ b/workbooks/acr_checklist.en_counters_workbook.json @@ -0,0 +1,837 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "497a107e-dde8-433e-b263-35ac8e8f7834", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": true, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": [ + "value::all" + ] + }, + { + "id": "844e4f4e-df51-4e3c-8eaf-0dc78b92c721", + "version": "KqlParameterItem/1.0", + "name": "OnlyFailed", + "label": "Only show failed", + "type": 2, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":true, \"label\":\"True\" },\r\n { \"value\":false, \"label\":\"False\", \"selected\":true }\r\n]" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "WorkbookSelectors" + }, + { + "type": 1, + "content": { + "json": "If you set \"Only show failed\" to \"Yes\", the different queries will only show items that have failed their compliance checks.", + "style": "info" + }, + "name": "InfoBox" + }, + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "crossComponentResources": [ + "value::all" + ], + "parameters": [ + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query0Stats", + "type": 1, + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query0FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query0Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query1Stats", + "type": 1, + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query1FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query2Stats", + "type": 1, + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query2FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query3Stats", + "type": 1, + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query3FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query4Stats", + "type": 1, + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query4FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query5Stats", + "type": 1, + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query5FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query5Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab1Success", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab1Total", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab1Percent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{Tab1Success}/{Tab1Total})" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "WorkbookTotal", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "WorkbookSuccess", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "WorkbookPercent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{WorkbookSuccess}/{WorkbookTotal})" + } + } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "InvisibleParameters" + }, + { + "type": 1, + "content": { + "json": "## Azure Container Registry Security Review\n\n---\n\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\n\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new)." + }, + "customWidth": "50", + "name": "MarkdownHeader" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"WorkbookPercent\\\": \\\"{WorkbookPercent}\\\", \\\"SubTitle\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "size": 4, + "queryType": 8, + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "WorkbookPercent", + "formatter": 4, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen" + } + }, + "subtitleContent": { + "columnMatch": "SubTitle", + "formatter": 1 + }, + "showBorder": true + } + }, + "customWidth": "50", + "name": "ProgressTile" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "0758d05b-2165-4f12-a410-ae6f33c6eec7", + "cellValue": "VisibleTab", + "linkTarget": "parameter", + "linkLabel": "Security ({Tab0Success:value}/{Tab0Total:value})", + "subTarget": "tab0", + "preText": "Security", + "style": "primary" + }, + { + "id": "d6ebb4e8-7216-4af7-a115-8be2ca5ada03", + "cellValue": "VisibleTab", + "linkTarget": "parameter", + "linkLabel": "Security ({Tab1Success:value}/{Tab1Total:value})", + "subTarget": "tab1", + "preText": "Security", + "style": "primary" + } + ] + }, + "name": "Tabs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Security" + }, + "name": "tab0title" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Security" + }, + "name": "tab1title" + }, + { + "type": 1, + "content": { + "json": "Encrypt registry with a customer managed key. Check [this link](https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys) for further information." + }, + "name": "querytext0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query0" + }, + { + "type": 1, + "content": { + "json": "Disable local authentication for management plane access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity) for further information." + }, + "name": "querytext1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query1" + }, + { + "type": 1, + "content": { + "json": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli) for further information." + }, + "name": "querytext2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query2" + }, + { + "type": 1, + "content": { + "json": "Disable Anonymous pull access. Check [this link](https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access) for further information." + }, + "name": "querytext3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query3" + }, + { + "type": 1, + "content": { + "json": "Disable Public Network access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access) for further information." + }, + "name": "querytext4" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query4" + }, + { + "type": 1, + "content": { + "json": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU). Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-skus) for further information." + }, + "name": "querytext5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query5" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/workbooks/acr_checklist.en_counters_workbook_template.json b/workbooks/acr_checklist.en_counters_workbook_template.json new file mode 100644 index 00000000..7b971f4b --- /dev/null +++ b/workbooks/acr_checklist.en_counters_workbook_template.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "workbookDisplayName": { + "type": "string", + "defaultValue": "Azure Container Registry Security Review", + "metadata": { + "description": "The friendly name for the workbook that is used in the Gallery or Saved List. Needs to be unique in the scope of the resource group and source" + } + }, + "workbookType": { + "type": "string", + "defaultValue": "workbook", + "metadata": { + "description": "The gallery that the workbook will be shown under. Supported values include workbook, `tsg`, Azure Monitor, etc." + } + }, + "workbookSourceId": { + "type": "string", + "defaultValue": "Azure Monitor", + "metadata": { + "description": "The id of resource instance to which the workbook will be associated" + } + }, + "workbookId": { + "type": "string", + "defaultValue": "[newGuid()]", + "metadata": { + "description": "The unique guid for this workbook instance" + } + } + }, + "resources": [ + { + "name": "[parameters('workbookId')]", + "type": "Microsoft.Insights/workbooks", + "location": "[resourceGroup().location]", + "kind": "shared", + "apiVersion": "2018-06-17-preview", + "dependsOn": [], + "properties": { + "displayName": "[parameters('workbookDisplayName')]", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Container Registry Security Review\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"0758d05b-2165-4f12-a410-ae6f33c6eec7\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d6ebb4e8-7216-4af7-a115-8be2ca5ada03\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Security\"\n },\n \"name\": \"tab0title\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Security\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Encrypt registry with a customer managed key. Check [this link](https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Disable local authentication for management plane access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Disable Anonymous pull access. Check [this link](https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Disable Public Network access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use an Azure Container Registry SKU that supports Private Link (Premium SKU). Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-skus) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "version": "1.0", + "sourceId": "[parameters('workbookSourceId')]", + "category": "[parameters('workbookType')]" + } + } + ], + "outputs": { + "workbookId": { + "type": "string", + "value": "[resourceId( 'Microsoft.Insights/workbooks', parameters('workbookId'))]" + } + } +} \ No newline at end of file diff --git a/workbooks/acr_checklist.en_workbook.json b/workbooks/acr_checklist.en_workbook.json new file mode 100644 index 00000000..d670f7fe --- /dev/null +++ b/workbooks/acr_checklist.en_workbook.json @@ -0,0 +1,512 @@ +{ + "version": "Notebook/1.0", + "items": [ + { + "type": 9, + "content": { + "version": "KqlParameterItem/1.0", + "parameters": [ + { + "id": "497a107e-dde8-433e-b263-35ac8e8f7834", + "version": "KqlParameterItem/1.0", + "name": "Subscription", + "type": 6, + "multiSelect": true, + "quote": "'", + "delimiter": ",", + "typeSettings": { + "additionalResourceOptions": [ + "value::all" + ], + "includeAll": true, + "showDefault": false + }, + "timeContext": { + "durationMs": 86400000 + }, + "value": [ + "value::all" + ] + }, + { + "id": "844e4f4e-df51-4e3c-8eaf-0dc78b92c721", + "version": "KqlParameterItem/1.0", + "name": "OnlyFailed", + "label": "Only show failed", + "type": 2, + "typeSettings": { + "additionalResourceOptions": [], + "showDefault": false + }, + "jsonData": "[\r\n { \"value\":true, \"label\":\"True\" },\r\n { \"value\":false, \"label\":\"False\", \"selected\":true }\r\n]" + } + ], + "style": "pills", + "queryType": 0, + "resourceType": "microsoft.operationalinsights/workspaces" + }, + "name": "WorkbookSelectors" + }, + { + "type": 1, + "content": { + "json": "If you set \"Only show failed\" to \"Yes\", the different queries will only show items that have failed their compliance checks.", + "style": "info" + }, + "name": "InfoBox" + }, + { + "type": 1, + "content": { + "json": "## Azure Container Registry Security Review\n\n---\n\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\n\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new)." + }, + "customWidth": "100", + "name": "MarkdownHeader" + }, + { + "type": 11, + "content": { + "version": "LinkItem/1.0", + "style": "tabs", + "links": [ + { + "id": "cf5981b3-681d-4a2c-b897-2eb4729d7bfa", + "cellValue": "VisibleTab", + "linkTarget": "parameter", + "linkLabel": "Security", + "subTarget": "tab0", + "preText": "Security", + "style": "primary" + }, + { + "id": "879625b5-e394-4c93-865e-068b19b7cbbb", + "cellValue": "VisibleTab", + "linkTarget": "parameter", + "linkLabel": "Security", + "subTarget": "tab1", + "preText": "Security", + "style": "primary" + } + ] + }, + "name": "Tabs" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Security" + }, + "name": "tab0title" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Security" + }, + "name": "tab1title" + }, + { + "type": 1, + "content": { + "json": "Encrypt registry with a customer managed key. Check [this link](https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys) for further information." + }, + "name": "querytext0" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query0" + }, + { + "type": 1, + "content": { + "json": "Disable local authentication for management plane access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity) for further information." + }, + "name": "querytext1" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query1" + }, + { + "type": 1, + "content": { + "json": "Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli) for further information." + }, + "name": "querytext2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query2" + }, + { + "type": 1, + "content": { + "json": "Disable Anonymous pull access. Check [this link](https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access) for further information." + }, + "name": "querytext3" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query3" + }, + { + "type": 1, + "content": { + "json": "Disable Public Network access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access) for further information." + }, + "name": "querytext4" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query4" + }, + { + "type": 1, + "content": { + "json": "Use an Azure Container Registry SKU that supports Private Link (Premium SKU). Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-skus) for further information." + }, + "name": "querytext5" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query5" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + } + ], + "$schema": "https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json" +} \ No newline at end of file diff --git a/workbooks/acr_checklist.en_workbook_template.json b/workbooks/acr_checklist.en_workbook_template.json new file mode 100644 index 00000000..fa9e21eb --- /dev/null +++ b/workbooks/acr_checklist.en_workbook_template.json @@ -0,0 +1,57 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "workbookDisplayName": { + "type": "string", + "defaultValue": "Azure Container Registry Security Review", + "metadata": { + "description": "The friendly name for the workbook that is used in the Gallery or Saved List. Needs to be unique in the scope of the resource group and source" + } + }, + "workbookType": { + "type": "string", + "defaultValue": "workbook", + "metadata": { + "description": "The gallery that the workbook will be shown under. Supported values include workbook, `tsg`, Azure Monitor, etc." + } + }, + "workbookSourceId": { + "type": "string", + "defaultValue": "Azure Monitor", + "metadata": { + "description": "The id of resource instance to which the workbook will be associated" + } + }, + "workbookId": { + "type": "string", + "defaultValue": "[newGuid()]", + "metadata": { + "description": "The unique guid for this workbook instance" + } + } + }, + "resources": [ + { + "name": "[parameters('workbookId')]", + "type": "Microsoft.Insights/workbooks", + "location": "[resourceGroup().location]", + "kind": "shared", + "apiVersion": "2018-06-17-preview", + "dependsOn": [], + "properties": { + "displayName": "[parameters('workbookDisplayName')]", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Container Registry Security Review\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"cf5981b3-681d-4a2c-b897-2eb4729d7bfa\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"879625b5-e394-4c93-865e-068b19b7cbbb\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Security\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Security\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Security\"\n },\n \"name\": \"tab0title\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Security\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Encrypt registry with a customer managed key. Check [this link](https://learn.microsoft.com/azure/container-registry/tutorial-customer-managed-keys) for further information.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend acrName = name, acrId = id | extend encryptionStatus = properties.encryption.status | extend compliant = iif(encryptionStatus == 'disabled', false, true) | project acrName, acrId, encryptionStatus, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Disable local authentication for management plane access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-authentication-managed-identity) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign AcrPull & AcrPush RBAC roles rather than granting Administrative access to identity principals. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-roles?tabs=azure-cli) for further information.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend localAdminDisabled = properties.adminUserEnabled // Adjust this property as needed | extend compliant = iif(localAdminDisabled == 'false', true, false) // Check if local admin is disabled | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Disable Anonymous pull access. Check [this link](https://learn.microsoft.com/azure/container-registry/anonymous-pull-access#configure-anonymous-pull-access) for further information.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.containerregistry/registries' | extend compliant = iif(properties.anonymousPullEnabled == false, true, false) | project compliant, name, id, tags | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Disable Public Network access. Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-access-selected-networks#disable-public-network-access) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | where sku.name =~ 'Premium' // Check for Premium SKU | extend publicAccessEnabled = properties.publicNetworkAccess | extend defaultAction = tostring(properties.networkRuleSet.defaultAction) // Extract defaultAction | extend compliant = iif(publicAccessEnabled != 'Enabled' or defaultAction == 'Deny', true, false) | project name, id, publicAccessEnabled, defaultAction, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use an Azure Container Registry SKU that supports Private Link (Premium SKU). Check [this link](https://learn.microsoft.com/azure/container-registry/container-registry-skus) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.ContainerRegistry/registries' | extend skuName = sku.name // Extract the SKU name | extend compliant = iif(skuName == 'Premium', true, false) // Check if SKU is Premium | project name, id, skuName, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "version": "1.0", + "sourceId": "[parameters('workbookSourceId')]", + "category": "[parameters('workbookType')]" + } + } + ], + "outputs": { + "workbookId": { + "type": "string", + "value": "[resourceId( 'Microsoft.Insights/workbooks', parameters('workbookId'))]" + } + } +} \ No newline at end of file diff --git a/workbooks/alz_checklist.en_network_counters.json b/workbooks/alz_checklist.en_network_counters.json index a2d9a280..0a13b0ce 100644 --- a/workbooks/alz_checklist.en_network_counters.json +++ b/workbooks/alz_checklist.en_network_counters.json @@ -1085,7 +1085,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}" + "resultVal": "{Query26Stats:$.Success}" } } ] @@ -1104,7 +1104,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}" + "resultVal": "{Query26Stats:$.Total}" } } ] @@ -1142,7 +1142,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Success}" + "resultVal": "{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}" } } ] @@ -1161,7 +1161,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Total}" + "resultVal": "{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}" } } ] @@ -1199,7 +1199,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}" + "resultVal": "{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" } } ] @@ -1218,7 +1218,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}" + "resultVal": "{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" } } ] @@ -1256,7 +1256,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" } } ] @@ -1275,7 +1275,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" } } ] @@ -1313,7 +1313,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" + "resultVal": "{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}" } } ] @@ -1332,7 +1332,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" + "resultVal": "{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}" } } ] @@ -1370,7 +1370,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}" + "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}" } } ] @@ -1389,7 +1389,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}" + "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}" } } ] @@ -1427,7 +1427,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query26Stats:$.Success}" + "resultVal": "{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}" } } ] @@ -1446,7 +1446,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query26Stats:$.Total}" + "resultVal": "{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}" } } ] @@ -1484,7 +1484,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" + "resultVal": "{Query9Stats:$.Success}" } } ] @@ -1503,7 +1503,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" + "resultVal": "{Query9Stats:$.Total}" } } ] @@ -1541,7 +1541,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}+{Query26Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" + "resultVal": "{Query26Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}+{Query9Stats:$.Total}" } } ] @@ -1560,7 +1560,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}+{Query26Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" + "resultVal": "{Query26Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}+{Query9Stats:$.Success}" } } ] @@ -1634,75 +1634,75 @@ "style": "tabs", "links": [ { - "id": "2c0e44ad-1cba-4338-bdd1-5bff5f71a8cd", + "id": "15e7fdcd-dcd4-4411-b6bd-3104cc56caa3", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN ({Tab0Success:value}/{Tab0Total:value})", + "linkLabel": "PaaS ({Tab0Success:value}/{Tab0Total:value})", "subTarget": "tab0", - "preText": "Virtual WAN", + "preText": "PaaS", "style": "primary" }, { - "id": "e4b5938a-4c84-436b-9a95-db3e502666b9", + "id": "f4a1c5df-be72-4190-8156-81674293f909", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet ({Tab1Success:value}/{Tab1Total:value})", + "linkLabel": "Firewall ({Tab1Success:value}/{Tab1Total:value})", "subTarget": "tab1", - "preText": "Internet", + "preText": "Firewall", "style": "primary" }, { - "id": "487ed80f-4ded-4dcb-b0e2-0227549a6375", + "id": "9bd2dcb1-f8a1-4bc1-987f-4e0eb2c7b1a4", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid ({Tab2Success:value}/{Tab2Total:value})", + "linkLabel": "IP plan ({Tab2Success:value}/{Tab2Total:value})", "subTarget": "tab2", - "preText": "Hybrid", + "preText": "IP plan", "style": "primary" }, { - "id": "4a151264-3650-4c93-bc8b-ab3a7fe7aa62", + "id": "5598416c-36f0-4b68-92ab-2f448ee1df8d", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Firewall ({Tab3Success:value}/{Tab3Total:value})", + "linkLabel": "Hub and spoke ({Tab3Success:value}/{Tab3Total:value})", "subTarget": "tab3", - "preText": "Firewall", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "d850cdff-f789-4ec2-91db-26cf7f6c6e62", + "id": "f78e2f6c-c8fe-41dc-a745-5dce5b92aca9", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan ({Tab4Success:value}/{Tab4Total:value})", + "linkLabel": "Segmentation ({Tab4Success:value}/{Tab4Total:value})", "subTarget": "tab4", - "preText": "IP plan", + "preText": "Segmentation", "style": "primary" }, { - "id": "44651f66-0386-4e11-ab22-0853e151d297", + "id": "f776ed7a-aa75-45dc-9f67-50e179a5115a", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation ({Tab5Success:value}/{Tab5Total:value})", + "linkLabel": "Hybrid ({Tab5Success:value}/{Tab5Total:value})", "subTarget": "tab5", - "preText": "Segmentation", + "preText": "Hybrid", "style": "primary" }, { - "id": "e8401296-627b-410a-981d-3692ea262349", + "id": "88faf0a8-f6ca-4b6d-a219-6bf07a69d102", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS ({Tab6Success:value}/{Tab6Total:value})", + "linkLabel": "Virtual WAN ({Tab6Success:value}/{Tab6Total:value})", "subTarget": "tab6", - "preText": "PaaS", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "e8fe57da-94d7-414e-9595-d5f1181d3a8e", + "id": "027d1088-db62-4519-a739-5dc5ba51dc9b", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke ({Tab7Success:value}/{Tab7Total:value})", + "linkLabel": "Internet ({Tab7Success:value}/{Tab7Total:value})", "subTarget": "tab7", - "preText": "Hub and spoke", + "preText": "Internet", "style": "primary" } ] @@ -1718,22 +1718,22 @@ { "type": 1, "content": { - "json": "## Virtual WAN" + "json": "## PaaS" }, "name": "tab0title" }, { "type": 1, "content": { - "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." }, - "name": "querytext32" + "name": "querytext26" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1782,20 +1782,42 @@ ] } }, - "name": "query32" + "name": "query26" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Firewall" + }, + "name": "tab1title" }, { "type": 1, "content": { - "json": "Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext33" + "name": "querytext17" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1844,20 +1866,20 @@ ] } }, - "name": "query33" + "name": "query17" }, { "type": 1, "content": { - "json": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "name": "querytext34" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1906,20 +1928,20 @@ ] } }, - "name": "query34" + "name": "query18" }, { "type": 1, "content": { - "json": "Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information." }, - "name": "querytext35" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1968,42 +1990,20 @@ ] } }, - "name": "query35" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Internet" - }, - "name": "tab1title" + "name": "query19" }, { "type": 1, "content": { - "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this." + "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "name": "querytext9" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2052,42 +2052,20 @@ ] } }, - "name": "query9" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab1" - }, - "name": "tab1" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Hybrid" - }, - "name": "tab2title" + "name": "query20" }, { "type": 1, "content": { - "json": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." }, - "name": "querytext10" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2136,20 +2114,20 @@ ] } }, - "name": "query10" + "name": "query21" }, { "type": 1, "content": { - "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this." }, - "name": "querytext11" + "name": "querytext23" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2198,20 +2176,20 @@ ] } }, - "name": "query11" + "name": "query23" }, { "type": 1, "content": { - "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this." }, - "name": "querytext12" + "name": "querytext24" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2260,20 +2238,20 @@ ] } }, - "name": "query12" + "name": "query24" }, { "type": 1, "content": { - "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information." }, - "name": "querytext13" + "name": "querytext25" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2322,20 +2300,42 @@ ] } }, - "name": "query13" + "name": "query25" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## IP plan" + }, + "name": "tab2title" }, { "type": 1, "content": { - "json": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." + "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext14" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2384,20 +2384,20 @@ ] } }, - "name": "query14" + "name": "query6" }, { "type": 1, "content": { - "json": "Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext15" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2446,20 +2446,20 @@ ] } }, - "name": "query15" + "name": "query7" }, { "type": 1, "content": { - "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." + "json": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this." }, - "name": "querytext16" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2508,7 +2508,7 @@ ] } }, - "name": "query16" + "name": "query8" } ] }, @@ -2528,22 +2528,22 @@ { "type": 1, "content": { - "json": "## Firewall" + "json": "## Hub and spoke" }, "name": "tab3title" }, { "type": 1, "content": { - "json": "Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this." }, - "name": "querytext17" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2592,20 +2592,20 @@ ] } }, - "name": "query17" + "name": "query0" }, { "type": 1, "content": { - "json": "Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext18" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2654,20 +2654,20 @@ ] } }, - "name": "query18" + "name": "query1" }, { "type": 1, "content": { - "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information." + "json": "Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext19" + "name": "querytext2" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2716,20 +2716,20 @@ ] } }, - "name": "query19" + "name": "query2" }, { "type": 1, "content": { - "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext20" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2778,20 +2778,20 @@ ] } }, - "name": "query20" + "name": "query3" }, { "type": 1, "content": { - "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." + "json": "Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." }, - "name": "querytext21" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2840,20 +2840,20 @@ ] } }, - "name": "query21" + "name": "query4" }, { "type": 1, "content": { - "json": "Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this." + "json": "Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." }, - "name": "querytext23" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2902,20 +2902,42 @@ ] } }, - "name": "query23" + "name": "query5" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab3" + }, + "name": "tab3" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Segmentation" + }, + "name": "tab4title" }, { "type": 1, "content": { - "json": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this." + "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "name": "querytext24" + "name": "querytext22" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2964,20 +2986,20 @@ ] } }, - "name": "query24" + "name": "query22" }, { "type": 1, "content": { - "json": "Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information." + "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." }, - "name": "querytext25" + "name": "querytext27" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3026,42 +3048,20 @@ ] } }, - "name": "query25" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab3" - }, - "name": "tab3" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## IP plan" - }, - "name": "tab4title" + "name": "query27" }, { "type": 1, "content": { - "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." }, - "name": "querytext6" + "name": "querytext28" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3110,20 +3110,20 @@ ] } }, - "name": "query6" + "name": "query28" }, { "type": 1, "content": { - "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." }, - "name": "querytext7" + "name": "querytext29" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3172,20 +3172,20 @@ ] } }, - "name": "query7" + "name": "query29" }, { "type": 1, "content": { - "json": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this." + "json": "Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this." }, - "name": "querytext8" + "name": "querytext30" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3234,42 +3234,20 @@ ] } }, - "name": "query8" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab4" - }, - "name": "tab4" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Segmentation" - }, - "name": "tab5title" + "name": "query30" }, { "type": 1, "content": { - "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this." }, - "name": "querytext22" + "name": "querytext31" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3318,20 +3296,42 @@ ] } }, - "name": "query22" + "name": "query31" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab4" + }, + "name": "tab4" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Hybrid" + }, + "name": "tab5title" }, { "type": 1, "content": { - "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." + "json": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext27" + "name": "querytext10" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3380,20 +3380,20 @@ ] } }, - "name": "query27" + "name": "query10" }, { "type": 1, "content": { - "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." + "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext28" + "name": "querytext11" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3442,20 +3442,20 @@ ] } }, - "name": "query28" + "name": "query11" }, { "type": 1, "content": { - "json": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." + "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext29" + "name": "querytext12" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3504,20 +3504,20 @@ ] } }, - "name": "query29" + "name": "query12" }, { "type": 1, "content": { - "json": "Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this." + "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext30" + "name": "querytext13" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3566,20 +3566,20 @@ ] } }, - "name": "query30" + "name": "query13" }, { "type": 1, "content": { - "json": "Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this." + "json": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." }, - "name": "querytext31" + "name": "querytext14" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3628,42 +3628,20 @@ ] } }, - "name": "query31" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab5" - }, - "name": "tab5" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## PaaS" - }, - "name": "tab6title" + "name": "query14" }, { "type": 1, "content": { - "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." + "json": "Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext26" + "name": "querytext15" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3712,42 +3690,20 @@ ] } }, - "name": "query26" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab6" - }, - "name": "tab6" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Hub and spoke" - }, - "name": "tab7title" + "name": "query15" }, { "type": 1, "content": { - "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this." + "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." }, - "name": "querytext0" + "name": "querytext16" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3796,20 +3752,42 @@ ] } }, - "name": "query0" + "name": "query16" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab5" + }, + "name": "tab5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Virtual WAN" + }, + "name": "tab6title" }, { "type": 1, "content": { - "json": "If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext1" + "name": "querytext32" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3858,20 +3836,20 @@ ] } }, - "name": "query1" + "name": "query32" }, { "type": 1, "content": { - "json": "Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext2" + "name": "querytext33" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3920,20 +3898,20 @@ ] } }, - "name": "query2" + "name": "query33" }, { "type": 1, "content": { - "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext3" + "name": "querytext34" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3982,20 +3960,20 @@ ] } }, - "name": "query3" + "name": "query34" }, { "type": 1, "content": { - "json": "Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." + "json": "Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext4" + "name": "querytext35" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -4044,20 +4022,42 @@ ] } }, - "name": "query4" + "name": "query35" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab6" + }, + "name": "tab6" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Internet" + }, + "name": "tab7title" }, { "type": 1, "content": { - "json": "Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." + "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this." }, - "name": "querytext5" + "name": "querytext9" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -4106,7 +4106,7 @@ ] } }, - "name": "query5" + "name": "query9" } ] }, diff --git a/workbooks/alz_checklist.en_network_counters_template.json b/workbooks/alz_checklist.en_network_counters_template.json index 82ad9a50..f5098ed1 100644 --- a/workbooks/alz_checklist.en_network_counters_template.json +++ b/workbooks/alz_checklist.en_network_counters_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query28Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query29Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query30Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query31Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query32Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33Stats\",\n \"type\": 1,\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query33Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query34Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query35Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab7Success}/{Tab7Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}+{Query9Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}+{Query26Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}+{Query9Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}+{Query26Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"2c0e44ad-1cba-4338-bdd1-5bff5f71a8cd\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e4b5938a-4c84-436b-9a95-db3e502666b9\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"487ed80f-4ded-4dcb-b0e2-0227549a6375\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4a151264-3650-4c93-bc8b-ab3a7fe7aa62\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Firewall ({Tab3Success:value}/{Tab3Total:value})\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Firewall\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"d850cdff-f789-4ec2-91db-26cf7f6c6e62\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan ({Tab4Success:value}/{Tab4Total:value})\",\n \"subTarget\": \"tab4\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"44651f66-0386-4e11-ab22-0853e151d297\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation ({Tab5Success:value}/{Tab5Total:value})\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e8401296-627b-410a-981d-3692ea262349\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS ({Tab6Success:value}/{Tab6Total:value})\",\n \"subTarget\": \"tab6\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"e8fe57da-94d7-414e-9595-d5f1181d3a8e\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke ({Tab7Success:value}/{Tab7Total:value})\",\n \"subTarget\": \"tab7\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext32\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query32\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext33\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query33\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext34\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query34\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext35\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query35\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Firewall\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext24\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query24\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information.\"\n },\n \"name\": \"querytext25\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query25\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext27\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query27\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext28\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query28\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext29\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query29\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext30\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query30\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query31\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query26\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab7title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query28Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query29Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query30Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query31Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query32Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33Stats\",\n \"type\": 1,\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query33Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query34Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query35Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab7Success}/{Tab7Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Total}+{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}+{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}+{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}+{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}+{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Success}+{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}+{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}+{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}+{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}+{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"15e7fdcd-dcd4-4411-b6bd-3104cc56caa3\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"f4a1c5df-be72-4190-8156-81674293f909\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Firewall ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Firewall\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"9bd2dcb1-f8a1-4bc1-987f-4e0eb2c7b1a4\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan ({Tab2Success:value}/{Tab2Total:value})\",\n \"subTarget\": \"tab2\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"5598416c-36f0-4b68-92ab-2f448ee1df8d\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke ({Tab3Success:value}/{Tab3Total:value})\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"f78e2f6c-c8fe-41dc-a745-5dce5b92aca9\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation ({Tab4Success:value}/{Tab4Total:value})\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"f776ed7a-aa75-45dc-9f67-50e179a5115a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid ({Tab5Success:value}/{Tab5Total:value})\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"88faf0a8-f6ca-4b6d-a219-6bf07a69d102\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN ({Tab6Success:value}/{Tab6Total:value})\",\n \"subTarget\": \"tab6\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"027d1088-db62-4519-a739-5dc5ba51dc9b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet ({Tab7Success:value}/{Tab7Total:value})\",\n \"subTarget\": \"tab7\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query26\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Firewall\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext24\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query24\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information.\"\n },\n \"name\": \"querytext25\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query25\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext27\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query27\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext28\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query28\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext29\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query29\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext30\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query30\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query31\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext32\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query32\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext33\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query33\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext34\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query34\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext35\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query35\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab7title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]" diff --git a/workbooks/alz_checklist.en_network_tabcounters.json b/workbooks/alz_checklist.en_network_tabcounters.json index 7d6cdda7..e5e834c4 100644 --- a/workbooks/alz_checklist.en_network_tabcounters.json +++ b/workbooks/alz_checklist.en_network_tabcounters.json @@ -70,70 +70,70 @@ "style": "tabs", "links": [ { - "id": "28e753d7-7a7c-4571-9461-727a7491e40c", + "id": "2bb68d8c-ed37-48f8-8fb1-0b5a2adbeada", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation", + "linkLabel": "Hub and spoke", "subTarget": "tab0", - "preText": "Segmentation", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "0d078392-5b10-400f-8cfe-5f102cfe432f", + "id": "b0076d4a-cb31-444f-8da1-6b6e1e4f6363", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet", + "linkLabel": "IP plan", "subTarget": "tab1", - "preText": "Internet", + "preText": "IP plan", "style": "primary" }, { - "id": "a4ae31cf-9d91-4adf-b04f-7bf0c4fb6461", + "id": "8ce6bf1c-fed3-4e46-a207-a554af0fef1f", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid", + "linkLabel": "Internet", "subTarget": "tab2", - "preText": "Hybrid", + "preText": "Internet", "style": "primary" }, { - "id": "44466922-4038-42c0-a640-3fa602c89f62", + "id": "24fbbf00-c66c-4447-88f8-a783b6caf015", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Firewall", + "linkLabel": "Segmentation", "subTarget": "tab3", - "preText": "Firewall", + "preText": "Segmentation", "style": "primary" }, { - "id": "998e7504-5f1e-41d6-8f61-331ec12599f3", + "id": "9ec632da-97b5-4443-b5dc-d3c4929f552c", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN", + "linkLabel": "Firewall", "subTarget": "tab4", - "preText": "Virtual WAN", + "preText": "Firewall", "style": "primary" }, { - "id": "4ab66f39-b8f1-4838-a5f1-1e8a8b700c9c", + "id": "c6af206c-a535-4809-915a-8015861b4857", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke", + "linkLabel": "Hybrid", "subTarget": "tab5", - "preText": "Hub and spoke", + "preText": "Hybrid", "style": "primary" }, { - "id": "445ec745-fcd6-4480-aa47-788f7558a7b5", + "id": "c0e41b97-e65b-416a-a413-8e0169403250", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan", + "linkLabel": "Virtual WAN", "subTarget": "tab6", - "preText": "IP plan", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "ee86cf1f-6a90-4dc3-8221-c81f11bf450b", + "id": "c2c71c6e-1119-4cee-8e9f-f09e9ab6b679", "cellValue": "VisibleTab", "linkTarget": "parameter", "linkLabel": "PaaS", @@ -162,9 +162,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query22Stats", + "name": "Query0Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -178,9 +178,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query22FullyCompliant", + "name": "Query0FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query22Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query0Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -190,9 +190,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query27Stats", + "name": "Query1Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -206,9 +206,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query27FullyCompliant", + "name": "Query1FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query27Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -218,9 +218,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query28Stats", + "name": "Query2Stats", "type": 1, - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -234,9 +234,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query28FullyCompliant", + "name": "Query2FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query28Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -246,9 +246,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query29Stats", + "name": "Query3Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -262,9 +262,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query29FullyCompliant", + "name": "Query3FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query29Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -274,9 +274,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query30Stats", + "name": "Query4Stats", "type": 1, - "query": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -290,9 +290,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query30FullyCompliant", + "name": "Query4FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query30Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -302,9 +302,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query31Stats", + "name": "Query5Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -318,9 +318,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query31FullyCompliant", + "name": "Query5FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query31Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query5Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -341,7 +341,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" } } ] @@ -360,7 +360,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" } } ] @@ -394,7 +394,7 @@ { "type": 1, "content": { - "json": "## Segmentation" + "json": "## Hub and spoke" }, "customWidth": "50", "name": "tab0title" @@ -435,15 +435,15 @@ { "type": 1, "content": { - "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this." }, - "name": "querytext22" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -492,20 +492,20 @@ ] } }, - "name": "query22" + "name": "query0" }, { "type": 1, "content": { - "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." + "json": "If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext27" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -554,20 +554,20 @@ ] } }, - "name": "query27" + "name": "query1" }, { "type": 1, "content": { - "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." + "json": "Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext28" + "name": "querytext2" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -616,20 +616,20 @@ ] } }, - "name": "query28" + "name": "query2" }, { "type": 1, "content": { - "json": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." + "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext29" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -678,20 +678,20 @@ ] } }, - "name": "query29" + "name": "query3" }, { "type": 1, "content": { - "json": "Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this." + "json": "Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." }, - "name": "querytext30" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -740,20 +740,20 @@ ] } }, - "name": "query30" + "name": "query4" }, { "type": 1, "content": { - "json": "Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this." + "json": "Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." }, - "name": "querytext31" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -802,7 +802,7 @@ ] } }, - "name": "query31" + "name": "query5" } ] }, @@ -830,9 +830,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query9Stats", + "name": "Query6Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -846,9 +846,65 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query9FullyCompliant", + "name": "Query6FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query9Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query6Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query7Stats", + "type": 1, + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query7FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query7Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query8Stats", + "type": 1, + "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query8FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query8Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -869,7 +925,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Success}" + "resultVal": "{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" } } ] @@ -888,7 +944,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query9Stats:$.Total}" + "resultVal": "{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" } } ] @@ -922,7 +978,7 @@ { "type": 1, "content": { - "json": "## Internet" + "json": "## IP plan" }, "customWidth": "50", "name": "tab1title" @@ -963,15 +1019,15 @@ { "type": 1, "content": { - "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this." + "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext9" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1020,409 +1076,23 @@ ] } }, - "name": "query9" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab1" - }, - "name": "tab1" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ + "name": "query6" + }, { - "type": 9, + "type": 1, "content": { - "version": "KqlParameterItem/1.0", - "crossComponentResources": [ - "{Subscription}" - ], - "parameters": [ - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query10Stats", - "type": 1, - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query10FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query10Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query11Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query11FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query11Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query12Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query12FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query12Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query13Stats", - "type": 1, - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query13FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query13Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query14Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query14FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query14Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query15Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query15FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query15Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query16Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query16FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query16Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab2Success", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab2Total", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}" - } - } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab2Percent", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "round(100*{Tab2Success}/{Tab2Total})" - } - } - ] - } - ], - "style": "pills", - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - "name": "TabInvisibleParameters" - }, - { - "type": 1, - "content": { - "json": "## Hybrid" - }, - "customWidth": "50", - "name": "tab2title" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab2Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", - "size": 3, - "queryType": 8, - "visualization": "tiles", - "tileSettings": { - "titleContent": { - "columnMatch": "Column1", - "formatter": 4, - "formatOptions": { - "min": 0, - "max": 100, - "palette": "redGreen" - }, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } - }, - "subtitleContent": { - "columnMatch": "Column2" - }, - "showBorder": true - } - }, - "customWidth": "50", - "name": "TabPercentTile" - }, - { - "type": 1, - "content": { - "json": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." - }, - "name": "querytext10" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } - }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } - }, - "name": "query10" - }, - { - "type": 1, - "content": { - "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." - }, - "name": "querytext11" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", + "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + }, + "name": "querytext7" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", "crossComponentResources": [ "{Subscription}" ], @@ -1468,20 +1138,20 @@ ] } }, - "name": "query11" + "name": "query7" }, { "type": 1, "content": { - "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this." }, - "name": "querytext12" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1530,206 +1200,176 @@ ] } }, - "name": "query12" - }, - { - "type": 1, - "content": { - "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." - }, - "name": "querytext13" - }, + "name": "query8" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ { - "type": 3, + "type": 9, "content": { - "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", + "version": "KqlParameterItem/1.0", "crossComponentResources": [ "{Subscription}" ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" + "parameters": [ + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query9Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query9FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query9Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab2Success", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query9Stats:$.Success}" } } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab2Total", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } - }, - "name": "query13" - }, - { - "type": 1, - "content": { - "json": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." - }, - "name": "querytext14" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "{Query9Stats:$.Total}" } } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab2Percent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{Tab2Success}/{Tab2Total})" + } } - } - ] - } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" }, - "name": "query14" + "name": "TabInvisibleParameters" }, { "type": 1, - "content": { - "json": "Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." - }, - "name": "querytext15" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } + "content": { + "json": "## Internet" + }, + "customWidth": "50", + "name": "tab2title" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab2Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "size": 3, + "queryType": 8, + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "Column1", + "formatter": 4, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen" }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" } } - ] + }, + "subtitleContent": { + "columnMatch": "Column2" + }, + "showBorder": true } }, - "name": "query15" + "customWidth": "50", + "name": "TabPercentTile" }, { "type": 1, "content": { - "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." + "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this." }, - "name": "querytext16" + "name": "querytext9" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1778,7 +1418,7 @@ ] } }, - "name": "query16" + "name": "query9" } ] }, @@ -1806,65 +1446,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query17Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query17FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query17Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query18Stats", - "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", - "crossComponentResources": [ - "{Subscription}" - ], - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query18FullyCompliant", - "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query18Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 - }, - "queryType": 8 - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Query19Stats", + "name": "Query22Stats", "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1878,9 +1462,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query19FullyCompliant", + "name": "Query22FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query19Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query22Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1890,9 +1474,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query20Stats", + "name": "Query27Stats", "type": 1, - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1906,9 +1490,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query20FullyCompliant", + "name": "Query27FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query20Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query27Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1918,9 +1502,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query21Stats", + "name": "Query28Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1934,9 +1518,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query21FullyCompliant", + "name": "Query28FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query21Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query28Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1946,9 +1530,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query23Stats", + "name": "Query29Stats", "type": 1, - "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1962,9 +1546,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query23FullyCompliant", + "name": "Query29FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query23Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query29Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -1974,9 +1558,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query24Stats", + "name": "Query30Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -1990,9 +1574,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query24FullyCompliant", + "name": "Query30FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query24Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query30Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2002,9 +1586,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query25Stats", + "name": "Query31Stats", "type": 1, - "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2018,9 +1602,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query25FullyCompliant", + "name": "Query31FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query25Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query31Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2041,7 +1625,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}" + "resultVal": "{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}" } } ] @@ -2060,7 +1644,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}" + "resultVal": "{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}" } } ] @@ -2079,195 +1663,71 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "round(100*{Tab3Success}/{Tab3Total})" - } - } - ] - } - ], - "style": "pills", - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" - }, - "name": "TabInvisibleParameters" - }, - { - "type": 1, - "content": { - "json": "## Firewall" - }, - "customWidth": "50", - "name": "tab3title" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab3Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", - "size": 3, - "queryType": 8, - "visualization": "tiles", - "tileSettings": { - "titleContent": { - "columnMatch": "Column1", - "formatter": 4, - "formatOptions": { - "min": 0, - "max": 100, - "palette": "redGreen" - }, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } - }, - "subtitleContent": { - "columnMatch": "Column2" - }, - "showBorder": true - } - }, - "customWidth": "50", - "name": "TabPercentTile" - }, - { - "type": 1, - "content": { - "json": "Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." - }, - "name": "querytext17" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" + "resultVal": "round(100*{Tab3Success}/{Tab3Total})" } } - }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" }, - "name": "query17" + "name": "TabInvisibleParameters" }, { "type": 1, "content": { - "json": "Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "## Segmentation" }, - "name": "querytext18" + "customWidth": "50", + "name": "tab3title" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 4, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab3Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "size": 3, + "queryType": 8, + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "Column1", + "formatter": 4, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen" }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" } } - ] + }, + "subtitleContent": { + "columnMatch": "Column2" + }, + "showBorder": true } }, - "name": "query18" + "customWidth": "50", + "name": "TabPercentTile" }, { "type": 1, "content": { - "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information." + "json": "Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "name": "querytext19" + "name": "querytext22" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2316,20 +1776,20 @@ ] } }, - "name": "query19" + "name": "query22" }, { "type": 1, "content": { - "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information." }, - "name": "querytext20" + "name": "querytext27" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2378,20 +1838,20 @@ ] } }, - "name": "query20" + "name": "query27" }, { "type": 1, "content": { - "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." + "json": "Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information." }, - "name": "querytext21" + "name": "querytext28" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2440,20 +1900,20 @@ ] } }, - "name": "query21" + "name": "query28" }, { "type": 1, "content": { - "json": "Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this." + "json": "Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this." }, - "name": "querytext23" + "name": "querytext29" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2502,20 +1962,20 @@ ] } }, - "name": "query23" + "name": "query29" }, { "type": 1, "content": { - "json": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this." + "json": "Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this." }, - "name": "querytext24" + "name": "querytext30" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2564,20 +2024,20 @@ ] } }, - "name": "query24" + "name": "query30" }, { "type": 1, "content": { - "json": "Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information." + "json": "Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this." }, - "name": "querytext25" + "name": "querytext31" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2626,7 +2086,7 @@ ] } }, - "name": "query25" + "name": "query31" } ] }, @@ -2654,9 +2114,121 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query32Stats", + "name": "Query17Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query17FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query17Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query18Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query18FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query18Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query19Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query19FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query19Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query20Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query20FullyCompliant", "type": 1, - "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query20Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query21Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2670,9 +2242,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query32FullyCompliant", + "name": "Query21FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query32Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query21Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2682,9 +2254,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query33Stats", + "name": "Query23Stats", "type": 1, - "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2698,9 +2270,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query33FullyCompliant", + "name": "Query23FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query33Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query23Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2710,9 +2282,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query34Stats", + "name": "Query24Stats", "type": 1, - "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2726,9 +2298,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query34FullyCompliant", + "name": "Query24FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query34Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query24Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2738,9 +2310,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query35Stats", + "name": "Query25Stats", "type": 1, - "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -2754,9 +2326,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query35FullyCompliant", + "name": "Query25FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query35Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query25Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -2777,7 +2349,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}" + "resultVal": "{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}" } } ] @@ -2796,90 +2368,338 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}" + "resultVal": "{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}" + } + } + ] + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Tab4Percent", + "type": 1, + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "criteriaData": [ + { + "criteriaContext": { + "operator": "Default", + "resultValType": "expression", + "resultVal": "round(100*{Tab4Success}/{Tab4Total})" + } + } + ] + } + ], + "style": "pills", + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + "name": "TabInvisibleParameters" + }, + { + "type": 1, + "content": { + "json": "## Firewall" + }, + "customWidth": "50", + "name": "tab4title" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab4Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", + "size": 3, + "queryType": 8, + "visualization": "tiles", + "tileSettings": { + "titleContent": { + "columnMatch": "Column1", + "formatter": 4, + "formatOptions": { + "min": 0, + "max": 100, + "palette": "redGreen" + }, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + "subtitleContent": { + "columnMatch": "Column2" + }, + "showBorder": true + } + }, + "customWidth": "50", + "name": "TabPercentTile" + }, + { + "type": 1, + "content": { + "json": "Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + }, + "name": "querytext17" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query17" + }, + { + "type": 1, + "content": { + "json": "Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + }, + "name": "querytext18" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query18" + }, + { + "type": 1, + "content": { + "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information." + }, + "name": "querytext19" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" } } - ] - }, - { - "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", - "version": "KqlParameterItem/1.0", - "name": "Tab4Percent", - "type": 1, - "isHiddenWhenLocked": true, - "timeContext": { - "durationMs": 86400000 }, - "criteriaData": [ - { - "criteriaContext": { - "operator": "Default", - "resultValType": "expression", - "resultVal": "round(100*{Tab4Success}/{Tab4Total})" - } + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] } - ] - } - ], - "style": "pills", - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources" + } + ] + } }, - "name": "TabInvisibleParameters" + "name": "query19" }, { "type": 1, "content": { - "json": "## Virtual WAN" + "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "customWidth": "50", - "name": "tab4title" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"Column1\\\": \\\"{Tab4Percent}\\\", \\\"Column2\\\": \\\"Percent of successful checks\\\"}\",\"transformers\":null}", - "size": 3, - "queryType": 8, - "visualization": "tiles", - "tileSettings": { - "titleContent": { - "columnMatch": "Column1", - "formatter": 4, - "formatOptions": { - "min": 0, - "max": 100, - "palette": "redGreen" + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } }, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] } } - }, - "subtitleContent": { - "columnMatch": "Column2" - }, - "showBorder": true + ] } }, - "customWidth": "50", - "name": "TabPercentTile" + "name": "query20" }, { "type": 1, "content": { - "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." }, - "name": "querytext32" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2928,20 +2748,20 @@ ] } }, - "name": "query32" + "name": "query21" }, { "type": 1, "content": { - "json": "Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this." }, - "name": "querytext33" + "name": "querytext23" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2990,20 +2810,20 @@ ] } }, - "name": "query33" + "name": "query23" }, { "type": 1, "content": { - "json": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this." }, - "name": "querytext34" + "name": "querytext24" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3052,20 +2872,20 @@ ] } }, - "name": "query34" + "name": "query24" }, { "type": 1, "content": { - "json": "Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information." }, - "name": "querytext35" + "name": "querytext25" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3114,7 +2934,7 @@ ] } }, - "name": "query35" + "name": "query25" } ] }, @@ -3142,9 +2962,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query0Stats", + "name": "Query10Stats", "type": 1, - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3158,9 +2978,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query0FullyCompliant", + "name": "Query10FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query0Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query10Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3170,9 +2990,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query1Stats", + "name": "Query11Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3186,9 +3006,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query1FullyCompliant", + "name": "Query11FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query1Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query11Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3198,9 +3018,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query2Stats", + "name": "Query12Stats", "type": 1, - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3214,9 +3034,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query2FullyCompliant", + "name": "Query12FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query2Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query12Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3226,9 +3046,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query3Stats", + "name": "Query13Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3242,9 +3062,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query3FullyCompliant", + "name": "Query13FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query3Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query13Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3254,9 +3074,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query4Stats", + "name": "Query14Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3270,9 +3090,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query4FullyCompliant", + "name": "Query14FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query4Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query14Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3282,9 +3102,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query5Stats", + "name": "Query15Stats", "type": 1, - "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3298,9 +3118,37 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query5FullyCompliant", + "name": "Query15FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query5Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query15Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query16Stats", + "type": 1, + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query16FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query16Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3321,7 +3169,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}" + "resultVal": "{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}" } } ] @@ -3340,7 +3188,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}" + "resultVal": "{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}" } } ] @@ -3374,7 +3222,7 @@ { "type": 1, "content": { - "json": "## Hub and spoke" + "json": "## Hybrid" }, "customWidth": "50", "name": "tab5title" @@ -3415,15 +3263,15 @@ { "type": 1, "content": { - "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this." + "json": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext0" + "name": "querytext10" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3472,20 +3320,20 @@ ] } }, - "name": "query0" + "name": "query10" }, { "type": 1, "content": { - "json": "If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext1" + "name": "querytext11" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3534,20 +3382,20 @@ ] } }, - "name": "query1" + "name": "query11" }, { "type": 1, "content": { - "json": "Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext2" + "name": "querytext12" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3596,20 +3444,20 @@ ] } }, - "name": "query2" + "name": "query12" }, { "type": 1, "content": { - "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext3" + "name": "querytext13" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3658,20 +3506,20 @@ ] } }, - "name": "query3" + "name": "query13" }, { "type": 1, "content": { - "json": "Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." + "json": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." }, - "name": "querytext4" + "name": "querytext14" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3720,20 +3568,20 @@ ] } }, - "name": "query4" + "name": "query14" }, { "type": 1, "content": { - "json": "Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." + "json": "Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext5" + "name": "querytext15" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -3782,7 +3630,69 @@ ] } }, - "name": "query5" + "name": "query15" + }, + { + "type": 1, + "content": { + "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." + }, + "name": "querytext16" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query16" } ] }, @@ -3810,9 +3720,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query6Stats", + "name": "Query32Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3826,9 +3736,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query6FullyCompliant", + "name": "Query32FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query6Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query32Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3838,9 +3748,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query7Stats", + "name": "Query33Stats", "type": 1, - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3854,9 +3764,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query7FullyCompliant", + "name": "Query33FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query7Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query33Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3866,9 +3776,9 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query8Stats", + "name": "Query34Stats", "type": 1, - "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", "crossComponentResources": [ "{Subscription}" ], @@ -3882,9 +3792,37 @@ { "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", "version": "KqlParameterItem/1.0", - "name": "Query8FullyCompliant", + "name": "Query34FullyCompliant", "type": 1, - "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query8Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query34Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 8 + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query35Stats", + "type": 1, + "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())", + "crossComponentResources": [ + "{Subscription}" + ], + "isHiddenWhenLocked": true, + "timeContext": { + "durationMs": 86400000 + }, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources" + }, + { + "id": "daf05c62-1d5b-4325-b241-d7ee468f23eb", + "version": "KqlParameterItem/1.0", + "name": "Query35FullyCompliant", + "type": 1, + "query": "{\"version\":\"1.0.0\",\"content\":\"{\\\"value\\\": \\\"{Query35Stats:$.FullyCompliant}\\\"}\",\"transformers\":null}", "isHiddenWhenLocked": true, "timeContext": { "durationMs": 86400000 @@ -3905,7 +3843,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" + "resultVal": "{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}" } } ] @@ -3924,7 +3862,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" + "resultVal": "{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}" } } ] @@ -3958,7 +3896,7 @@ { "type": 1, "content": { - "json": "## IP plan" + "json": "## Virtual WAN" }, "customWidth": "50", "name": "tab6title" @@ -3999,15 +3937,15 @@ { "type": 1, "content": { - "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext6" + "name": "querytext32" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -4056,20 +3994,20 @@ ] } }, - "name": "query6" + "name": "query32" }, { "type": 1, "content": { - "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext7" + "name": "querytext33" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -4118,20 +4056,20 @@ ] } }, - "name": "query7" + "name": "query33" }, { "type": 1, "content": { - "json": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this." + "json": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext8" + "name": "querytext34" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -4180,7 +4118,69 @@ ] } }, - "name": "query8" + "name": "query34" + }, + { + "type": 1, + "content": { + "json": "Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + }, + "name": "querytext35" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 4, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query35" } ] }, diff --git a/workbooks/alz_checklist.en_network_tabcounters_template.json b/workbooks/alz_checklist.en_network_tabcounters_template.json index 7c08c8d3..6a7e19f5 100644 --- a/workbooks/alz_checklist.en_network_tabcounters_template.json +++ b/workbooks/alz_checklist.en_network_tabcounters_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"28e753d7-7a7c-4571-9461-727a7491e40c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"0d078392-5b10-400f-8cfe-5f102cfe432f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"a4ae31cf-9d91-4adf-b04f-7bf0c4fb6461\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"44466922-4038-42c0-a640-3fa602c89f62\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Firewall\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Firewall\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"998e7504-5f1e-41d6-8f61-331ec12599f3\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4ab66f39-b8f1-4838-a5f1-1e8a8b700c9c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"445ec745-fcd6-4480-aa47-788f7558a7b5\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab6\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"ee86cf1f-6a90-4dc3-8221-c81f11bf450b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab7\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query28Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query29Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query30Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query31Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab0title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab0Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext27\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query27\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext28\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query28\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext29\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query29\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext30\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query30\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query31\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab1title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab1Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab2title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab2Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Firewall\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab3title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab3Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext24\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query24\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information.\"\n },\n \"name\": \"querytext25\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query25\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query32Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33Stats\",\n \"type\": 1,\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query33Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query34Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query35Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab4title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab4Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext32\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query32\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext33\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query33\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext34\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query34\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext35\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query35\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab5title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab5Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab6title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab6Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab7Success}/{Tab7Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab7title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab7Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query26\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"2bb68d8c-ed37-48f8-8fb1-0b5a2adbeada\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"b0076d4a-cb31-444f-8da1-6b6e1e4f6363\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab1\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"8ce6bf1c-fed3-4e46-a207-a554af0fef1f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"24fbbf00-c66c-4447-88f8-a783b6caf015\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"9ec632da-97b5-4443-b5dc-d3c4929f552c\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Firewall\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Firewall\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"c6af206c-a535-4809-915a-8015861b4857\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"c0e41b97-e65b-416a-a413-8e0169403250\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab6\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"c2c71c6e-1119-4cee-8e9f-f09e9ab6b679\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab7\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query1Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query1Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab0title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab0Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab1title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab1Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query9FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query9Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query9Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab2Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab2Success}/{Tab2Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab2title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab2Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query22FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query22Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query27FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query27Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query28FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query28Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query29FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query29Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query30FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query30Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query31FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query31Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Success}+{Query27Stats:$.Success}+{Query28Stats:$.Success}+{Query29Stats:$.Success}+{Query30Stats:$.Success}+{Query31Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query22Stats:$.Total}+{Query27Stats:$.Total}+{Query28Stats:$.Total}+{Query29Stats:$.Total}+{Query30Stats:$.Total}+{Query31Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab3Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab3Success}/{Tab3Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab3title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab3Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext27\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query27\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext28\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query28\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext29\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query29\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext30\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query30\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query31\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query17FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query17Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query18FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query18Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query19FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query19Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query20FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query20Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query21FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query21Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query23FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query23Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query24FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query24Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled'| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query25FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query25Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Success}+{Query18Stats:$.Success}+{Query19Stats:$.Success}+{Query20Stats:$.Success}+{Query21Stats:$.Success}+{Query23Stats:$.Success}+{Query24Stats:$.Success}+{Query25Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query17Stats:$.Total}+{Query18Stats:$.Total}+{Query19Stats:$.Total}+{Query20Stats:$.Total}+{Query21Stats:$.Total}+{Query23Stats:$.Total}+{Query24Stats:$.Total}+{Query25Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab4Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab4Success}/{Tab4Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Firewall\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab4title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab4Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext24\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query24\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information.\"\n },\n \"name\": \"querytext25\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query25\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query10FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query10Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query11FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query11Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query12FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query12Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13Stats\",\n \"type\": 1,\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query13FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query13Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query14FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query14Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2)| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query15FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query15Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation))| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query16FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query16Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Success}+{Query11Stats:$.Success}+{Query12Stats:$.Success}+{Query13Stats:$.Success}+{Query14Stats:$.Success}+{Query15Stats:$.Success}+{Query16Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query10Stats:$.Total}+{Query11Stats:$.Total}+{Query12Stats:$.Total}+{Query13Stats:$.Total}+{Query14Stats:$.Total}+{Query15Stats:$.Total}+{Query16Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab5Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab5Success}/{Tab5Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab5title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab5Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query32FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query32Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33Stats\",\n \"type\": 1,\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query33FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query33Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query34FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query34Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query35FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query35Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Success}+{Query33Stats:$.Success}+{Query34Stats:$.Success}+{Query35Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query32Stats:$.Total}+{Query33Stats:$.Total}+{Query34Stats:$.Total}+{Query35Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab6Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab6Success}/{Tab6Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab6title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab6Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext32\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query32\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext33\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query33\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext34\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query34\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext35\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query35\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query26FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query26Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query26Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab7Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab7Success}/{Tab7Total})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"TabInvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"customWidth\": \"50\",\n \"name\": \"tab7title\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"Column1\\\\\\\": \\\\\\\"{Tab7Percent}\\\\\\\", \\\\\\\"Column2\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 3,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"Column1\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n },\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"Column2\"\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"TabPercentTile\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query26\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]" diff --git a/workbooks/alz_checklist.en_network_workbook.json b/workbooks/alz_checklist.en_network_workbook.json index 912efe1f..ca334de0 100644 --- a/workbooks/alz_checklist.en_network_workbook.json +++ b/workbooks/alz_checklist.en_network_workbook.json @@ -70,75 +70,75 @@ "style": "tabs", "links": [ { - "id": "e2ba09ba-9340-4b67-8d5e-c450fbbefb85", + "id": "f61a0d4c-2695-448c-9ada-13ee0ac53d67", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "IP plan", + "linkLabel": "PaaS", "subTarget": "tab0", - "preText": "IP plan", + "preText": "PaaS", "style": "primary" }, { - "id": "96eaa1ff-69db-4816-ad3d-522d2d62ad4b", + "id": "4fb25230-b891-4471-a5a6-9cee47247902", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Virtual WAN", + "linkLabel": "Hub and spoke", "subTarget": "tab1", - "preText": "Virtual WAN", + "preText": "Hub and spoke", "style": "primary" }, { - "id": "b1df5234-6b66-48c6-ac3b-2392e96eae51", + "id": "41453cc2-8f5e-4339-bcfe-c46e2187e35f", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Segmentation", + "linkLabel": "Internet", "subTarget": "tab2", - "preText": "Segmentation", + "preText": "Internet", "style": "primary" }, { - "id": "1b12900e-60ba-435e-86bc-b2ae7d4c6895", + "id": "7bff8a2d-6e7a-42a4-bbf5-bfa0762c17f9", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hybrid", + "linkLabel": "Segmentation", "subTarget": "tab3", - "preText": "Hybrid", + "preText": "Segmentation", "style": "primary" }, { - "id": "0ea6fe14-9eca-4df0-8f43-528cb43bf21a", + "id": "ffa32124-531b-4554-add6-11d6908abe70", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "PaaS", + "linkLabel": "Virtual WAN", "subTarget": "tab4", - "preText": "PaaS", + "preText": "Virtual WAN", "style": "primary" }, { - "id": "ac6fe09c-e2c7-44fd-a78a-e8092215e691", + "id": "afaf130a-4adc-483f-85a6-65d5958fdba5", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Internet", + "linkLabel": "Hybrid", "subTarget": "tab5", - "preText": "Internet", + "preText": "Hybrid", "style": "primary" }, { - "id": "5fc57124-054d-415b-b266-603d5994bae8", + "id": "abfb3865-aeec-4509-8a26-be3f89b36419", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Hub and spoke", + "linkLabel": "Firewall", "subTarget": "tab6", - "preText": "Hub and spoke", + "preText": "Firewall", "style": "primary" }, { - "id": "6bed81f0-d5e6-42e0-8094-027a7b55ea30", + "id": "73353f6d-2201-4a6e-ab87-71ecfb80e8a3", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Firewall", + "linkLabel": "IP plan", "subTarget": "tab7", - "preText": "Firewall", + "preText": "IP plan", "style": "primary" } ] @@ -154,22 +154,22 @@ { "type": 1, "content": { - "json": "## IP plan" + "json": "## PaaS" }, "name": "tab0title" }, { "type": 1, "content": { - "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." }, - "name": "querytext6" + "name": "querytext26" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -218,20 +218,42 @@ ] } }, - "name": "query6" + "name": "query26" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Hub and spoke" + }, + "name": "tab1title" }, { "type": 1, "content": { - "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." + "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this." }, - "name": "querytext7" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -280,20 +302,20 @@ ] } }, - "name": "query7" + "name": "query0" }, { "type": 1, "content": { - "json": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this." + "json": "If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext8" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -342,42 +364,82 @@ ] } }, - "name": "query8" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ + "name": "query1" + }, { "type": 1, "content": { - "json": "## Virtual WAN" + "json": "Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "tab1title" + "name": "querytext2" + }, + { + "type": 3, + "content": { + "version": "KqlItem/1.0", + "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "size": 0, + "queryType": 1, + "resourceType": "microsoft.resourcegraph/resources", + "crossComponentResources": [ + "{Subscription}" + ], + "gridSettings": { + "formatters": [ + { + "columnMatch": "id", + "formatter": 0, + "numberFormat": { + "unit": 0, + "options": { + "style": "decimal" + } + } + }, + { + "columnMatch": "compliant", + "formatter": 18, + "formatOptions": { + "thresholdsOptions": "icons", + "thresholdsGrid": [ + { + "operator": "==", + "thresholdValue": "1", + "representation": "success", + "text": "Success" + }, + { + "operator": "==", + "thresholdValue": "0", + "representation": "failed", + "text": "Failed" + }, + { + "operator": "Default", + "thresholdValue": null, + "representation": "unknown", + "text": "Unknown" + } + ] + } + } + ] + } + }, + "name": "query2" }, { "type": 1, "content": { - "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." }, - "name": "querytext32" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -426,20 +488,20 @@ ] } }, - "name": "query32" + "name": "query3" }, { "type": 1, "content": { - "json": "Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." }, - "name": "querytext33" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -488,20 +550,20 @@ ] } }, - "name": "query33" + "name": "query4" }, { "type": 1, "content": { - "json": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." }, - "name": "querytext34" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -550,20 +612,42 @@ ] } }, - "name": "query34" + "name": "query5" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab1" + }, + "name": "tab1" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Internet" + }, + "name": "tab2title" }, { "type": 1, "content": { - "json": "Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." + "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this." }, - "name": "querytext35" + "name": "querytext9" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -612,16 +696,16 @@ ] } }, - "name": "query35" + "name": "query9" } ] }, "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab1" + "value": "tab2" }, - "name": "tab1" + "name": "tab2" }, { "type": 12, @@ -634,7 +718,7 @@ "content": { "json": "## Segmentation" }, - "name": "tab2title" + "name": "tab3title" }, { "type": 1, @@ -1013,9 +1097,9 @@ "conditionalVisibility": { "parameterName": "VisibleTab", "comparison": "isEqualTo", - "value": "tab2" + "value": "tab3" }, - "name": "tab2" + "name": "tab3" }, { "type": 12, @@ -1026,22 +1110,22 @@ { "type": 1, "content": { - "json": "## Hybrid" + "json": "## Virtual WAN" }, - "name": "tab3title" + "name": "tab4title" }, { "type": 1, "content": { - "json": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext10" + "name": "querytext32" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1090,20 +1174,20 @@ ] } }, - "name": "query10" + "name": "query32" }, { "type": 1, "content": { - "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext11" + "name": "querytext33" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1152,20 +1236,20 @@ ] } }, - "name": "query11" + "name": "query33" }, { "type": 1, "content": { - "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext12" + "name": "querytext34" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1214,20 +1298,20 @@ ] } }, - "name": "query12" + "name": "query34" }, { "type": 1, "content": { - "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this." }, - "name": "querytext13" + "name": "querytext35" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1276,82 +1360,42 @@ ] } }, - "name": "query13" - }, + "name": "query35" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab4" + }, + "name": "tab4" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ { "type": 1, "content": { - "json": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." - }, - "name": "querytext14" - }, - { - "type": 3, - "content": { - "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", - "size": 0, - "queryType": 1, - "resourceType": "microsoft.resourcegraph/resources", - "crossComponentResources": [ - "{Subscription}" - ], - "gridSettings": { - "formatters": [ - { - "columnMatch": "id", - "formatter": 0, - "numberFormat": { - "unit": 0, - "options": { - "style": "decimal" - } - } - }, - { - "columnMatch": "compliant", - "formatter": 18, - "formatOptions": { - "thresholdsOptions": "icons", - "thresholdsGrid": [ - { - "operator": "==", - "thresholdValue": "1", - "representation": "success", - "text": "Success" - }, - { - "operator": "==", - "thresholdValue": "0", - "representation": "failed", - "text": "Failed" - }, - { - "operator": "Default", - "thresholdValue": null, - "representation": "unknown", - "text": "Unknown" - } - ] - } - } - ] - } + "json": "## Hybrid" }, - "name": "query14" + "name": "tab5title" }, { "type": 1, "content": { - "json": "Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." + "json": "Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext15" + "name": "querytext10" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1400,20 +1444,20 @@ ] } }, - "name": "query15" + "name": "query10" }, { "type": 1, "content": { - "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." + "json": "Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext16" + "name": "querytext11" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1462,42 +1506,20 @@ ] } }, - "name": "query16" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab3" - }, - "name": "tab3" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## PaaS" - }, - "name": "tab4title" + "name": "query11" }, { "type": 1, "content": { - "json": "Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this." + "json": "Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext26" + "name": "querytext12" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1546,42 +1568,20 @@ ] } }, - "name": "query26" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab4" - }, - "name": "tab4" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Internet" - }, - "name": "tab5title" + "name": "query12" }, { "type": 1, "content": { - "json": "Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this." + "json": "Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext9" + "name": "querytext13" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1630,42 +1630,20 @@ ] } }, - "name": "query9" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab5" - }, - "name": "tab5" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Hub and spoke" - }, - "name": "tab6title" + "name": "query13" }, { "type": 1, "content": { - "json": "If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this." + "json": "Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this." }, - "name": "querytext0" + "name": "querytext14" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1714,20 +1692,20 @@ ] } }, - "name": "query0" + "name": "query14" }, { "type": 1, "content": { - "json": "If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this." }, - "name": "querytext1" + "name": "querytext15" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1776,20 +1754,20 @@ ] } }, - "name": "query1" + "name": "query15" }, { "type": 1, "content": { - "json": "Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information." }, - "name": "querytext2" + "name": "querytext16" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1838,20 +1816,42 @@ ] } }, - "name": "query2" + "name": "query16" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab5" + }, + "name": "tab5" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Firewall" + }, + "name": "tab6title" }, { "type": 1, "content": { - "json": "Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this." + "json": "Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." }, - "name": "querytext3" + "name": "querytext17" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1900,20 +1900,20 @@ ] } }, - "name": "query3" + "name": "query17" }, { "type": 1, "content": { - "json": "Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." + "json": "Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "name": "querytext4" + "name": "querytext18" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1962,20 +1962,20 @@ ] } }, - "name": "query4" + "name": "query18" }, { "type": 1, "content": { - "json": "Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information." + "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information." }, - "name": "querytext5" + "name": "querytext19" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2024,42 +2024,20 @@ ] } }, - "name": "query5" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab6" - }, - "name": "tab6" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## Firewall" - }, - "name": "tab7title" + "name": "query19" }, { "type": 1, "content": { - "json": "Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this." + "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." }, - "name": "querytext17" + "name": "querytext20" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2108,20 +2086,20 @@ ] } }, - "name": "query17" + "name": "query20" }, { "type": 1, "content": { - "json": "Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." }, - "name": "querytext18" + "name": "querytext21" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2170,20 +2148,20 @@ ] } }, - "name": "query18" + "name": "query21" }, { "type": 1, "content": { - "json": "Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information." + "json": "Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this." }, - "name": "querytext19" + "name": "querytext23" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2232,20 +2210,20 @@ ] } }, - "name": "query19" + "name": "query23" }, { "type": 1, "content": { - "json": "Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this." + "json": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this." }, - "name": "querytext20" + "name": "querytext24" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2294,20 +2272,20 @@ ] } }, - "name": "query20" + "name": "query24" }, { "type": 1, "content": { - "json": "For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information." + "json": "Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information." }, - "name": "querytext21" + "name": "querytext25" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2356,20 +2334,42 @@ ] } }, - "name": "query21" + "name": "query25" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab6" + }, + "name": "tab6" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## IP plan" + }, + "name": "tab7title" }, { "type": 1, "content": { - "json": "Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this." + "json": "Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext23" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\.|172\\.(1[6-9]|2[0-9]|3[01])\\.|192\\.168\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2418,20 +2418,20 @@ ] } }, - "name": "query23" + "name": "query6" }, { "type": 1, "content": { - "json": "Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this." + "json": "Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this." }, - "name": "querytext24" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2480,20 +2480,20 @@ ] } }, - "name": "query24" + "name": "query7" }, { "type": 1, "content": { - "json": "Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information." + "json": "Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this." }, - "name": "querytext25" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 0, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -2542,7 +2542,7 @@ ] } }, - "name": "query25" + "name": "query8" } ] }, diff --git a/workbooks/alz_checklist.en_network_workbook_template.json b/workbooks/alz_checklist.en_network_workbook_template.json index d6ec4a98..0feac9e1 100644 --- a/workbooks/alz_checklist.en_network_workbook_template.json +++ b/workbooks/alz_checklist.en_network_workbook_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"e2ba09ba-9340-4b67-8d5e-c450fbbefb85\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab0\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"96eaa1ff-69db-4816-ad3d-522d2d62ad4b\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"b1df5234-6b66-48c6-ac3b-2392e96eae51\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"1b12900e-60ba-435e-86bc-b2ae7d4c6895\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"0ea6fe14-9eca-4df0-8f43-528cb43bf21a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab4\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"ac6fe09c-e2c7-44fd-a78a-e8092215e691\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"5fc57124-054d-415b-b266-603d5994bae8\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab6\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"6bed81f0-d5e6-42e0-8094-027a7b55ea30\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Firewall\",\n \"subTarget\": \"tab7\",\n \"preText\": \"Firewall\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext32\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query32\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext33\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query33\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext34\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query34\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext35\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query35\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext27\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query27\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext28\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query28\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext29\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query29\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext30\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query30\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query31\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query26\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Firewall\"\n },\n \"name\": \"tab7title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext24\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query24\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information.\"\n },\n \"name\": \"querytext25\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query25\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Landing Zone Review - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"f61a0d4c-2695-448c-9ada-13ee0ac53d67\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"PaaS\",\n \"subTarget\": \"tab0\",\n \"preText\": \"PaaS\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4fb25230-b891-4471-a5a6-9cee47247902\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hub and spoke\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Hub and spoke\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"41453cc2-8f5e-4339-bcfe-c46e2187e35f\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Internet\",\n \"subTarget\": \"tab2\",\n \"preText\": \"Internet\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"7bff8a2d-6e7a-42a4-bbf5-bfa0762c17f9\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Segmentation\",\n \"subTarget\": \"tab3\",\n \"preText\": \"Segmentation\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"ffa32124-531b-4554-add6-11d6908abe70\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Virtual WAN\",\n \"subTarget\": \"tab4\",\n \"preText\": \"Virtual WAN\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"afaf130a-4adc-483f-85a6-65d5958fdba5\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Hybrid\",\n \"subTarget\": \"tab5\",\n \"preText\": \"Hybrid\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"abfb3865-aeec-4509-8a26-be3f89b36419\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Firewall\",\n \"subTarget\": \"tab6\",\n \"preText\": \"Firewall\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"73353f6d-2201-4a6e-ab87-71ecfb80e8a3\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"IP plan\",\n \"subTarget\": \"tab7\",\n \"preText\": \"IP plan\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## PaaS\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't enable virtual network service endpoints by default on all subnets. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-service-endpoints-overview) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/?source=learn) can help to educate yourself on this.\"\n },\n \"name\": \"querytext26\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets = properties.subnets | mv-expand subnets | project id = subnets.id, resourceGroup, VNet = name, serviceEndpoints = subnets.properties.serviceEndpoints, compliant = (isnull(subnets.properties.serviceEndpoints) or array_length(subnets.properties.serviceEndpoints) == 0) | order by compliant asc | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query26\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hub and spoke\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If using Route Server, use a /27 prefix for the Route Server subnet. Check [this link](https://learn.microsoft.com/azure/route-server/quickstart-configure-route-server-portal#create-a-route-server-1) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-route-server/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'RouteServerSubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you have more than 400 spoke networks in a region, deploy an additional hub to bypass VNet peering limits (500) and the maximum number of prefixes that can be advertised via ExpressRoute (1000). Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | summarize peeringcount = count() by id | extend compliant = (peeringcount < 450) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Limit the number of routes per route table to 400. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits?toc=/azure/virtual-network/toc.json#azure-resource-manager-virtual-networking-limits) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/routetables' | mvexpand properties.routes | summarize routeCount = count() by id | extend compliant = (routeCount < 360) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use the setting 'Allow traffic to remote virtual network' when configuring VNet peerings. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-network-manage-peering) for further information.. [This training](https://learn.microsoft.com/training/modules/hub-and-spoke-network-architecture/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | project id, peeringName=properties_virtualNetworkPeerings.name, compliant = (properties_virtualNetworkPeerings.properties.allowVirtualNetworkAccess == True) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard Load Balancer SKU with a zone-redundant deployment, Selecting Standard SKU Load Balancer enhances reliability through availability zones and zone resiliency, ensuring deployments withstand zone and region failures. Unlike Basic, it supports global load balancing and offers an SLA. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PrivateSubnetId = toupper(feIPconfigs.properties.subnet.id), PrivateIPZones = feIPconfigs.zones, PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PrivateSubnetId) | where isnull(PrivateIPZones) or array_length(PrivateIPZones) < 2 | project name, feConfigName, id | union (resources | where type == 'microsoft.network/loadbalancers' | where tolower(sku.name) != 'basic' | mv-expand feIPconfigs = properties.frontendIPConfigurations | extend feConfigName = (feIPconfigs.name), PIPid = toupper(feIPconfigs.properties.publicIPAddress.id), JoinID = toupper(id) | where isnotempty(PIPid) | join kind=innerunique ( resources | where type == 'microsoft.network/publicipaddresses' | where isnull(zones) or array_length(zones) < 2 | extend LBid = toupper(substring(properties.ipConfiguration.id, 0, indexof(properties.ipConfiguration.id, '/frontendIPConfigurations'))), InnerID = toupper(id) ) on $left.PIPid == $right.InnerID) | project name, id, tags, param1='Zones: No Zone or Zonal', param2=strcat('Frontend IP Configuration:', ' ', feConfigName) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure load balancer backend pool(s) contains at least two instances, Deploying Azure Load Balancers with at least two instances in the backend prevents a single point of failure and supports scalability. Check [this link](https://learn.microsoft.com/en-us/azure/reliability/reliability-load-balancer?tabs=graph#zone-redundant) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/loadBalancers' | extend bep = properties.backendAddressPools | extend BackEndPools = array_length(bep) | where BackEndPools == 0 | project name, id, Param1='backendPools', Param2=toint(0), tags | union (resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Standard' | extend bep = properties.backendAddressPools | extend BackEndPools = toint(array_length(bep)) | mv-expand bip = properties.backendAddressPools | extend BackendAddresses = array_length(bip.properties.loadBalancerBackendAddresses) | where toint(BackendAddresses) <= 1 | project name, id, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | union ( resources | where type =~ 'Microsoft.Network/loadBalancers' | where sku.name == 'Basic' | mv-expand properties.backendAddressPools | extend backendPoolId = properties_backendAddressPools.id | project id, name, tags, tostring(backendPoolId), Param1='BackEndPools' | join kind = leftouter ( resources | where type =~ 'Microsoft.Network/networkInterfaces' | mv-expand properties.ipConfigurations | mv-expand properties_ipConfigurations.properties.loadBalancerBackendAddressPools | extend backendPoolId = tostring(properties_ipConfigurations_properties_loadBalancerBackendAddressPools.id) | summarize poolMembers = count() by backendPoolId | project tostring(backendPoolId), poolMembers ) on backendPoolId | where toint(poolMembers) <= 1 | extend BackendAddresses = poolMembers | project id, name, tags, Param1='backendAddresses', Param2=toint(BackendAddresses)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Internet\"\n },\n \"name\": \"tab2title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Bastion in a subnet /26 or larger. Check [this link](https://learn.microsoft.com/azure/bastion/bastion-faq#subnet) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-bastion/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext9\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureBastionSubnet' | extend compliant = (subnetPrefixLength <= 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query9\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab2\"\n },\n \"name\": \"tab2\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Segmentation\"\n },\n \"name\": \"tab3title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use a /26 prefix for your Azure Firewall subnets. Check [this link](https://learn.microsoft.com/azure/firewall/firewall-faq#why-does-azure-firewall-need-a--26-subnet-size) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext22\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'AzureFirewallSubnet' | extend compliant = (subnetPrefixLength == 26) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query22\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use at least a /27 prefix for your Gateway subnets. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-howto-add-gateway-resource-manager#add-a-gateway) for further information.\"\n },\n \"name\": \"querytext27\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | project id, subnetName = subnets.name, subnetPrefix = subnets.properties.addressPrefix | extend subnetPrefixLength = split(subnetPrefix, '/')[1] | where subnetName == 'GatewaySubnet' | extend compliant = (subnetPrefixLength <= 27) | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query27\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Don't rely on the NSG inbound default rules using the VirtualNetwork service tag to limit connectivity. Check [this link](https://learn.microsoft.com/azure/virtual-network/service-tags-overview#available-service-tags) for further information.\"\n },\n \"name\": \"querytext28\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/networksecuritygroups' | mvexpand properties.securityRules | project id,name,ruleAction=properties_securityRules.properties.access,rulePriority=properties_securityRules.properties.priority,ruleDst=properties_securityRules.properties.destinationAddressPrefix,ruleSrc=properties_securityRules.properties.sourceAddressPrefix,ruleProt=properties_securityRules.properties.protocol,ruleDirection=properties_securityRules.properties.direction,rulePort=properties_securityRules.properties.destinationPortRange | summarize StarDenies=countif(ruleAction=='Deny' and ruleDst=='*' and ruleSrc=='*' and ruleProt=='*' and rulePort=='*') by id,tostring(ruleDirection) | where ruleDirection == 'Inbound' | project id,compliant=(StarDenies>0) | union (resources | where type=='microsoft.network/networksecuritygroups' | where array_length(properties.securityRules)==0 | extend compliant=false | project id,compliant) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query28\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use NSGs to help protect traffic across subnets, as well as east/west traffic across the platform (traffic between landing zones). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-landing-zone-network-segmentation) for further information.. [This training](https://learn.microsoft.com/learn/paths/implement-network-security/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext29\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | mv-expand subnet = properties.subnets | where subnet.name !in~ ('GatewaySubnet', 'AzureFirewallSubnet', 'AzureFirewallManagementSubnet', 'RouteServerSubnet') | extend compliant = iff(isnotnull(subnet.properties.networkSecurityGroup.id), true, false) | project id, subnetName = subnet.name, vnetName = name, NSG = subnet.properties.networkSecurityGroup.id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query29\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable VNet Flow Logs and feed them into Traffic Analytics to gain insights into internal and external traffic flows. Check [this link](https://learn.microsoft.com/azure/network-watcher/vnet-flow-logs-overview) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-network-monitoring/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext30\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/virtualnetworks' | project subscriptionId, lowerCaseVNetId = tolower(id) | join kind = leftouter ( resources | where type =~ 'microsoft.network/networkwatchers/flowlogs' and properties.enabled == true and properties.provisioningState =~ 'succeeded' | where properties.targetResourceId contains '/Microsoft.Network/virtualNetworks/' | project flowlogId = id, trafficAnalyticsEnabled = properties.flowAnalyticsConfiguration.networkWatcherFlowAnalyticsConfiguration.enabled, lowerCaseTargetVNetId = tolower(properties.targetResourceId) ) on $left.lowerCaseVNetId == $right.lowerCaseTargetVNetId | extend compliant = iff(isnotempty(lowerCaseTargetVNetId), true, false) | project id = lowerCaseVNetId, flowlogId, trafficAnalyticsEnabled, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query30\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not implement more than 900 NSG rules per NSG, due to the limit of 1000 rules. Check [this link](https://learn.microsoft.com/azure/azure-resource-manager/management/azure-subscription-service-limits) for further information.. [This training](https://learn.microsoft.com/azure/virtual-network/network-security-group-how-it-works) can help to educate yourself on this.\"\n },\n \"name\": \"querytext31\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/networksecuritygroups' | project id, rules = array_length(properties.securityRules) | project id, compliant = (rules < 900) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query31\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab3\"\n },\n \"name\": \"tab3\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Virtual WAN\"\n },\n \"name\": \"tab4title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For outbound Internet traffic protection and filtering, deploy Azure Firewall in secured hubs. Check [this link](https://learn.microsoft.com/azure/virtual-wan/howto-firewall) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext32\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualhubs' | extend compliant = isnotnull(properties.azureFirewall.id) | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query32\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Do not disable branch-to-branch traffic in Virtual WAN, unless these flows should be explicitly blocked. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#is-branch-to-branch-connectivity-allowed-in-virtual-wan) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext33\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type =~ 'microsoft.network/virtualwans' | extend compliant= (properties.allowBranchToBranchTraffic == 'true') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query33\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use AS-Path as hub routing preference, since it is more flexible than ExpressRoute or VPN. Check [this link](https://learn.microsoft.com/azure/virtual-wan/about-virtual-hub-routing-preference) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext34\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs'| extend compliant= (properties.hubRoutingPreference =~ 'ASPath') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query34\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Assign at least a /23 prefix to virtual hubs to ensure enough IP space is available. Check [this link](https://learn.microsoft.com/azure/virtual-wan/virtual-wan-faq#what-is-the-recommended-hub-address-space-during-hub-creation) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-virtual-wan/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext35\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/virtualhubs' | extend addressSpace = properties.addressPrefix | extend compliant= (toint(substring(addressSpace, indexof(addressSpace, '/') + 1)) < 23) | distinct name, id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query35\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab4\"\n },\n \"name\": \"tab4\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Hybrid\"\n },\n \"name\": \"tab5title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Select the right SKU for the ExpressRoute/VPN gateways based on bandwidth and performance requirements. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways?source=recommendations#gwsku) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext10\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier !in ('Basic', 'Standard')| project name, id, subscriptionId, resourceGroup, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query10\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that you're using unlimited-data ExpressRoute circuits only if you reach the bandwidth that justifies their cost. Check [this link](https://learn.microsoft.com/azure/expressroute/plan-manage-cost) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext11\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/expressroutecircuits' | extend compliant = (tolower(sku.family) == 'metereddata' or tolower(sku.tier) == 'local') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query11\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Leverage the Local SKU of ExpressRoute to reduce the cost of your circuits, if your circuit peering location supports your Azure regions for the Local SKU. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-faqs#expressroute-local) for further information.. [This training](https://learn.microsoft.com/training/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext12\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project id, gwid=tostring(properties.virtualNetworkGateway1.id), circuitid=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitid=tostring(id), circuitsku=sku.tier) on circuitid | project id=gwid, compliant = (circuitsku == 'Local') | summarize compliant=max(compliant) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query12\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy a zone-redundant ExpressRoute gateway in the supported Azure regions. Check [this link](https://learn.microsoft.com/azure/expressroute/expressroute-about-virtual-network-gateways) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext13\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources| where type == 'microsoft.network/virtualnetworkgateways'| where properties.gatewayType =~ 'vpn' or properties.gatewayType == 'ExpressRoute'| extend SKUName = properties.sku.name, SKUTier = properties.sku.tier, Type = properties.gatewayType| extend compliant = SKUTier contains 'AZ'| project name, id, subscriptionId, resourceGroup, Type, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query13\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use zone-redundant VPN gateways to connect branches or remote locations to Azure (where available). Check [this link](https://learn.microsoft.com/azure/vpn-gateway/create-zone-redundant-vnet-gateway) for further information.. [This training](https://learn.microsoft.com/training/modules/intro-to-azure-vpn-gateway/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext14\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworkgateways' | where properties.gatewayType == 'Vpn' | extend compliant = (tolower(properties.sku.name) contains 'az') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query14\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use ExpressRoute circuits from different peering locations for redundancy. Check [this link](https://learn.microsoft.com/azure/expressroute/designing-for-disaster-recovery-with-expressroute-privatepeering#need-for-redundant-connectivity-solution) for further information.. [This training](https://learn.microsoft.com/learn/modules/design-implement-azure-expressroute/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext15\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/connections' | where properties.connectionType == 'ExpressRoute' | project cxId=id, gwId=tostring(properties.virtualNetworkGateway1.id), circuitId=tostring(properties.peer.id) | join (resources | where type=='microsoft.network/expressroutecircuits' | project circuitId=tostring(id), circuitLocation=tostring(properties.serviceProviderProperties.peeringLocation)) on circuitId | distinct gwId, circuitLocation | summarize countErLocations=count() by id=gwId | extend compliant = (countErLocations >= 2) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query15\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you are using a route table in the GatewaySubnet, make sure that gateway routes are propagated. Check [this link](https://learn.microsoft.com/azure/vpn-gateway/vpn-gateway-about-vpn-gateway-settings#gwsub) for further information.\"\n },\n \"name\": \"querytext16\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,resourceGroup,name,subnetName=tostring(subnets.name),routeTableId=tostring(subnets.properties.routeTable.id) | where subnetName == 'GatewaySubnet' | join kind=leftouter (Resources | where type == 'microsoft.network/routetables' | project routeTableName=name,routeTableId=id, disableBgpRoutePropagation=properties.disableBgpRoutePropagation) on routeTableId | project id,compliant = (disableBgpRoutePropagation == False or isnull(disableBgpRoutePropagation)) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query16\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab5\"\n },\n \"name\": \"tab5\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Firewall\"\n },\n \"name\": \"tab6title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use application rules to filter outbound traffic on destination host name for supported protocols. Use FQDN-based network rules and Azure Firewall with DNS proxy to filter egress traffic to the Internet over other protocols. Check [this link](https://learn.microsoft.com/azure/firewall/fqdn-filtering-network-rules) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-networking-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext17\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.dnsSettings.enableProxy == true) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query17\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure Firewall Premium to enable additional security features. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext18\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.sku.tier == 'Premium') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query18\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall Threat Intelligence mode to Alert and Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps-signature-rules) for further information.\"\n },\n \"name\": \"querytext19\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.threatIntelMode == 'Deny') | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query19\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure Azure Firewall IDPS mode to Deny for additional protection. Check [this link](https://learn.microsoft.com/azure/firewall/premium-features#idps) for further information.. [This training](https://learn.microsoft.com/training/modules/introduction-azure-firewall/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext20\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/firewallpolicies' | extend compliant = (properties.intrusionDetection.mode == 'Deny') | project id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query20\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"For subnets in VNets not connected to Virtual WAN, attach a route table so that Internet traffic is redirected to Azure Firewall or a Network Virtual Appliance. Check [this link](https://learn.microsoft.com/azure/virtual-network/virtual-networks-udr-overview) for further information.\"\n },\n \"name\": \"querytext21\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/virtualnetworks' | project id,resourceGroup,name,subnets=properties.subnets | mv-expand subnets | project id,name,subnetId=tostring(subnets.id), subnetName=tostring(subnets.name),subnetRT=subnets.properties.routeTable.id | where not (subnetName in ('GatewaySubnet', 'AzureFirewallSubnet', 'RouteServerSubnet', 'AzureBastionSubnet')) | extend hasRT = isnotnull(subnetRT) | distinct id, hasRT, subnetId | join kind=fullouter (resources | where type == 'microsoft.network/virtualnetworks' | mvexpand properties.virtualNetworkPeerings | extend isVWAN=(tolower(split(properties_virtualNetworkPeerings.name, '_')[0]) == 'remotevnettohubpeering') | mv-expand properties.subnets | project id, isVWAN, name, subnetId=tostring(properties_subnets.id), subnetName=tostring(properties_subnets.name) | summarize PeeredToVWAN=max(isVWAN) by id, subnetId | project id, subnetId, isVWANpeer = (PeeredToVWAN == true)) on subnetId | project id=iff(isnotempty(id), id, id1), subnetId=iff(isnotempty(subnetId), subnetId, subnetId1), hasRT, isVWANpeer | extend compliant = (hasRT==true or isVWANpeer==true) | distinct id, subnetId, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query21\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable Azure Firewall DNS proxy configuration. Check [this link](https://learn.microsoft.com/azure/firewall/dns-details) for further information.. [This training](https://learn.microsoft.com/training/courses/az-700t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext23\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/firewallPolicies' | where array_length(properties.firewalls) > 0 | extend compliant = (properties.dnsSettings.enableProxy =~ 'true') | distinct id, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query23\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Azure Firewall across multiple availability zones. Azure Firewall offers different SLAs depending on its deployment; in a single availability zone or across multiple, potentially improving reliability and performance. Check [this link](https://learn.microsoft.com/azure/firewall/deploy-availability-zone-powershell) for further information.. [This training](https://learn.microsoft.com/training/courses/az-104t00/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext24\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/azurefirewalls' | where array_length(zones) <= 1 or isnull(zones) | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | project name, id, tags, param1='multipleZones:false' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query24\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure DDoS Protection on the Azure Firewall VNet, Associate a DDoS protection plan with the virtual network hosting Azure Firewall to provide enhanced mitigation against DDoS attacks. Azure Firewall Manager integrates the creation of firewall infrastructure and DDoS protection plans. Check [this link](https://learn.microsoft.com/en-gb/azure/ddos-protection/ddos-protection-overview) for further information.\"\n },\n \"name\": \"querytext25\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'Microsoft.Network/azureFirewalls' | where isempty(properties.virtualHub.id) or isnull(properties.virtualHub.id) | mv-expand ipConfig = properties.ipConfigurations | project name, firewallId = id, tags, vNetName = split(ipConfig.properties.subnet.id, '/', 8)[0], vNetId = tolower(substring(ipConfig.properties.subnet.id, 0, indexof(ipConfig.properties.subnet.id, /subnet'))) | join kind=fullouter ( resources | where type =~ 'Microsoft.Network/ddosProtectionPlans' | mv-expand vNet = properties.virtualNetworks | project ddosProtectionPlanId = id, vNetId = tolower(vNet.id) ) on vNetId | where isempty(ddosProtectionPlanId) | , name, id = firewallId, tags, param1 = strcat('vNet: ', vNetName), param2 = 'ddosProtection: Disabled' | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query25\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab6\"\n },\n \"name\": \"tab6\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## IP plan\"\n },\n \"name\": \"tab7title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use IP addresses from the address allocation ranges for private internets (RFC 1918). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | project name, id, location, resourceGroup, subscriptionId, cidr = addressPrefix | extend compliant = (cidr matches regex @'^(10\\\\.|172\\\\.(1[6-9]|2[0-9]|3[01])\\\\.|192\\\\.168\\\\.)') | project id, compliant, cidr | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure that IP address space isn't wasted, don't create unnecessarily large virtual networks (for example /16). Check [this link](https://learn.microsoft.com/azure/cloud-adoption-framework/ready/azure-best-practices/plan-for-ip-addressing) for further information.. [This training](https://learn.microsoft.com/learn/paths/architect-network-infrastructure/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/virtualnetworks' | extend addressSpace = todynamic(properties.addressSpace) | extend addressPrefix = todynamic(properties.addressSpace.addressPrefixes) | mvexpand addressSpace | mvexpand addressPrefix | extend addressMask = split(addressPrefix,'/')[1] | extend compliant = addressMask > 16 | project name, id, subscriptionId, resourceGroup, addressPrefix, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Standard SKU and Zone-Redundant IPs when applicable, Public IP addresses in Azure can be of standard SKU, available as non-zonal, zonal, or zone-redundant. Zone-redundant IPs are accessible across all zones, resisting any single zone failure, thereby providing higher resilience. Check [this link](https://learn.microsoft.com/azure/virtual-network/ip-services/public-ip-addresses#availability-zone) for further information.. [This training](https://learn.microsoft.com/en-gb/training/modules/configure-virtual-networks/6-create-public-ip-addressing) can help to educate yourself on this.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"Resources | where type =~ 'Microsoft.Network/publicIPAddresses' and sku.tier =~ 'Regional' | where isempty(zones) or array_length(zones) <= 1 | extend az = case(isempty(zones), 'Non-zonal', array_length(zones) <= 1, strcat('Zonal (', strcat_array(zones, ','), ')'), zones) | project name, id, tags, param1 = strcat('sku: ', sku.name), param2 = strcat('availabilityZone: ', az) | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 0,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab7\"\n },\n \"name\": \"tab7\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]" diff --git a/workbooks/appdelivery_checklist.en_network_counters_workbook.json b/workbooks/appdelivery_checklist.en_network_counters_workbook.json index c6571c22..49f8925b 100644 --- a/workbooks/appdelivery_checklist.en_network_counters_workbook.json +++ b/workbooks/appdelivery_checklist.en_network_counters_workbook.json @@ -329,7 +329,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query1Stats:$.Success}+{Query5Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" } } ] @@ -348,7 +348,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query1Stats:$.Total}+{Query5Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" } } ] @@ -386,7 +386,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" + "resultVal": "{Query1Stats:$.Success}+{Query5Stats:$.Success}" } } ] @@ -405,7 +405,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" + "resultVal": "{Query1Stats:$.Total}+{Query5Stats:$.Total}" } } ] @@ -443,7 +443,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query1Stats:$.Total}+{Query5Stats:$.Total}+{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}" + "resultVal": "{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query1Stats:$.Total}+{Query5Stats:$.Total}" } } ] @@ -462,7 +462,7 @@ "criteriaContext": { "operator": "Default", "resultValType": "expression", - "resultVal": "{Query1Stats:$.Success}+{Query5Stats:$.Success}+{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}" + "resultVal": "{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query1Stats:$.Success}+{Query5Stats:$.Success}" } } ] @@ -536,21 +536,21 @@ "style": "tabs", "links": [ { - "id": "5031dcb4-ce6e-4c07-a7f7-205dbb020f2a", + "id": "91159469-bde1-4bed-bd6c-9b3b294168f6", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Load Balancer ({Tab0Success:value}/{Tab0Total:value})", + "linkLabel": "App Gateway ({Tab0Success:value}/{Tab0Total:value})", "subTarget": "tab0", - "preText": "Load Balancer", + "preText": "App Gateway", "style": "primary" }, { - "id": "fccd1b99-ca6b-4e1b-9e46-c8dd6e43e849", + "id": "47b09ba0-098a-4032-8af5-af757a4c47f1", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "App Gateway ({Tab1Success:value}/{Tab1Total:value})", + "linkLabel": "Load Balancer ({Tab1Success:value}/{Tab1Total:value})", "subTarget": "tab1", - "preText": "App Gateway", + "preText": "Load Balancer", "style": "primary" } ] @@ -566,22 +566,22 @@ { "type": 1, "content": { - "json": "## Load Balancer" + "json": "## App Gateway" }, "name": "tab0title" }, { "type": 1, "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." + "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext1" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -630,20 +630,20 @@ ] } }, - "name": "query1" + "name": "query0" }, { "type": 1, "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." + "json": "Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext5" + "name": "querytext2" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -692,42 +692,20 @@ ] } }, - "name": "query5" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## App Gateway" - }, - "name": "tab1title" + "name": "query2" }, { "type": 1, "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext0" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -776,20 +754,20 @@ ] } }, - "name": "query0" + "name": "query3" }, { "type": 1, "content": { - "json": "Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext2" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -838,20 +816,20 @@ ] } }, - "name": "query2" + "name": "query4" }, { "type": 1, "content": { - "json": "Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information." }, - "name": "querytext3" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -900,20 +878,20 @@ ] } }, - "name": "query3" + "name": "query6" }, { "type": 1, "content": { - "json": "Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information." }, - "name": "querytext4" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -962,20 +940,20 @@ ] } }, - "name": "query4" + "name": "query7" }, { "type": 1, "content": { - "json": "Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information." + "json": "You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information." }, - "name": "querytext6" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1024,20 +1002,42 @@ ] } }, - "name": "query6" + "name": "query8" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Load Balancer" + }, + "name": "tab1title" }, { "type": 1, "content": { - "json": "Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information." + "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." }, - "name": "querytext7" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1086,20 +1086,20 @@ ] } }, - "name": "query7" + "name": "query1" }, { "type": 1, "content": { - "json": "You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information." + "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." }, - "name": "querytext8" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -1148,7 +1148,7 @@ ] } }, - "name": "query8" + "name": "query5" } ] }, diff --git a/workbooks/appdelivery_checklist.en_network_counters_workbook_template.json b/workbooks/appdelivery_checklist.en_network_counters_workbook_template.json index 89737f71..f6864e32 100644 --- a/workbooks/appdelivery_checklist.en_network_counters_workbook_template.json +++ b/workbooks/appdelivery_checklist.en_network_counters_workbook_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query1Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query1Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query1Stats:$.Total}+{Query5Stats:$.Total}+{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query1Stats:$.Success}+{Query5Stats:$.Success}+{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Application Delivery Networking - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"5031dcb4-ce6e-4c07-a7f7-205dbb020f2a\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Load Balancer ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Load Balancer\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"fccd1b99-ca6b-4e1b-9e46-c8dd6e43e849\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App Gateway ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"App Gateway\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Load Balancer\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## App Gateway\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"crossComponentResources\": [\n \"value::all\"\n ],\n \"parameters\": [\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query0FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query0Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard')| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query1FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query1Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query2FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query2Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query3FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query3Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query4FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query4Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5Stats\",\n \"type\": 1,\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query5FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query5Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query6FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query6Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7Stats\",\n \"type\": 1,\n \"query\": \"resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query7FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query7Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8Stats\",\n \"type\": 1,\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant| summarize Total = count(), Success = countif(compliant==1), Failed = countif(compliant==0) | extend SuccessPercent = iff(Total==0, 100, 100*toint(Success)/toint(Total)) | extend FullyCompliant = iff(SuccessPercent == 100, 'Yes', 'No') | project Query1Stats=tostring(pack_all())\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Query8FullyCompliant\",\n \"type\": 1,\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"value\\\\\\\": \\\\\\\"{Query8Stats:$.FullyCompliant}\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"queryType\": 8\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab0Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab0Success}/{Tab0Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Success\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query1Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Total\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query1Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Tab1Percent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{Tab1Success}/{Tab1Total})\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookTotal\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Total}+{Query2Stats:$.Total}+{Query3Stats:$.Total}+{Query4Stats:$.Total}+{Query6Stats:$.Total}+{Query7Stats:$.Total}+{Query8Stats:$.Total}+{Query1Stats:$.Total}+{Query5Stats:$.Total}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookSuccess\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"{Query0Stats:$.Success}+{Query2Stats:$.Success}+{Query3Stats:$.Success}+{Query4Stats:$.Success}+{Query6Stats:$.Success}+{Query7Stats:$.Success}+{Query8Stats:$.Success}+{Query1Stats:$.Success}+{Query5Stats:$.Success}\"\n }\n }\n ]\n },\n {\n \"id\": \"daf05c62-1d5b-4325-b241-d7ee468f23eb\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"WorkbookPercent\",\n \"type\": 1,\n \"isHiddenWhenLocked\": true,\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"criteriaData\": [\n {\n \"criteriaContext\": {\n \"operator\": \"Default\",\n \"resultValType\": \"expression\",\n \"resultVal\": \"round(100*{WorkbookSuccess}/{WorkbookTotal})\"\n }\n }\n ]\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\"\n },\n \"name\": \"InvisibleParameters\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Application Delivery Networking - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"50\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"{\\\"version\\\":\\\"1.0.0\\\",\\\"content\\\":\\\"{\\\\\\\"WorkbookPercent\\\\\\\": \\\\\\\"{WorkbookPercent}\\\\\\\", \\\\\\\"SubTitle\\\\\\\": \\\\\\\"Percent of successful checks\\\\\\\"}\\\",\\\"transformers\\\":null}\",\n \"size\": 4,\n \"queryType\": 8,\n \"visualization\": \"tiles\",\n \"tileSettings\": {\n \"titleContent\": {\n \"columnMatch\": \"WorkbookPercent\",\n \"formatter\": 4,\n \"formatOptions\": {\n \"min\": 0,\n \"max\": 100,\n \"palette\": \"redGreen\"\n }\n },\n \"subtitleContent\": {\n \"columnMatch\": \"SubTitle\",\n \"formatter\": 1\n },\n \"showBorder\": true\n }\n },\n \"customWidth\": \"50\",\n \"name\": \"ProgressTile\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"91159469-bde1-4bed-bd6c-9b3b294168f6\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App Gateway ({Tab0Success:value}/{Tab0Total:value})\",\n \"subTarget\": \"tab0\",\n \"preText\": \"App Gateway\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"47b09ba0-098a-4032-8af5-af757a4c47f1\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Load Balancer ({Tab1Success:value}/{Tab1Total:value})\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Load Balancer\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## App Gateway\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Load Balancer\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]" diff --git a/workbooks/appdelivery_checklist.en_network_workbook.json b/workbooks/appdelivery_checklist.en_network_workbook.json index 77f81d67..7e0246e2 100644 --- a/workbooks/appdelivery_checklist.en_network_workbook.json +++ b/workbooks/appdelivery_checklist.en_network_workbook.json @@ -70,21 +70,21 @@ "style": "tabs", "links": [ { - "id": "d2797f6a-633c-487c-bbbc-e6e0ef7bdc78", + "id": "476f3f66-d6c1-4afc-97cf-e43fa43711a9", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "Load Balancer", + "linkLabel": "App Gateway", "subTarget": "tab0", - "preText": "Load Balancer", + "preText": "App Gateway", "style": "primary" }, { - "id": "bf2db8b9-6cdc-42fd-9cb6-f4febd9d9140", + "id": "4a68032b-c8a0-45dc-b535-68029ac69a00", "cellValue": "VisibleTab", "linkTarget": "parameter", - "linkLabel": "App Gateway", + "linkLabel": "Load Balancer", "subTarget": "tab1", - "preText": "App Gateway", + "preText": "Load Balancer", "style": "primary" } ] @@ -100,22 +100,22 @@ { "type": 1, "content": { - "json": "## Load Balancer" + "json": "## App Gateway" }, "name": "tab0title" }, { "type": 1, "content": { - "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." + "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext1" + "name": "querytext0" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -164,20 +164,20 @@ ] } }, - "name": "query1" + "name": "query0" }, { "type": 1, "content": { - "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." + "json": "Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext5" + "name": "querytext2" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -226,42 +226,20 @@ ] } }, - "name": "query5" - } - ] - }, - "conditionalVisibility": { - "parameterName": "VisibleTab", - "comparison": "isEqualTo", - "value": "tab0" - }, - "name": "tab0" - }, - { - "type": 12, - "content": { - "version": "NotebookGroup/1.0", - "groupType": "editable", - "items": [ - { - "type": 1, - "content": { - "json": "## App Gateway" - }, - "name": "tab1title" + "name": "query2" }, { "type": 1, "content": { - "json": "Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext0" + "name": "querytext3" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -310,20 +288,20 @@ ] } }, - "name": "query0" + "name": "query3" }, { "type": 1, "content": { - "json": "Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." }, - "name": "querytext2" + "name": "querytext4" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -372,20 +350,20 @@ ] } }, - "name": "query2" + "name": "query4" }, { "type": 1, "content": { - "json": "Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information." }, - "name": "querytext3" + "name": "querytext6" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -434,20 +412,20 @@ ] } }, - "name": "query3" + "name": "query6" }, { "type": 1, "content": { - "json": "Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this." + "json": "Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information." }, - "name": "querytext4" + "name": "querytext7" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -496,20 +474,20 @@ ] } }, - "name": "query4" + "name": "query7" }, { "type": 1, "content": { - "json": "Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information." + "json": "You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information." }, - "name": "querytext6" + "name": "querytext8" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -558,20 +536,42 @@ ] } }, - "name": "query6" + "name": "query8" + } + ] + }, + "conditionalVisibility": { + "parameterName": "VisibleTab", + "comparison": "isEqualTo", + "value": "tab0" + }, + "name": "tab0" + }, + { + "type": 12, + "content": { + "version": "NotebookGroup/1.0", + "groupType": "editable", + "items": [ + { + "type": 1, + "content": { + "json": "## Load Balancer" + }, + "name": "tab1title" }, { "type": 1, "content": { - "json": "Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information." + "json": "Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information." }, - "name": "querytext7" + "name": "querytext1" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -620,20 +620,20 @@ ] } }, - "name": "query7" + "name": "query1" }, { "type": 1, "content": { - "json": "You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information." + "json": "Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information." }, - "name": "querytext8" + "name": "querytext5" }, { "type": 3, "content": { "version": "KqlItem/1.0", - "query": "resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", + "query": "resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed", "size": 4, "queryType": 1, "resourceType": "microsoft.resourcegraph/resources", @@ -682,7 +682,7 @@ ] } }, - "name": "query8" + "name": "query5" } ] }, diff --git a/workbooks/appdelivery_checklist.en_network_workbook_template.json b/workbooks/appdelivery_checklist.en_network_workbook_template.json index cbc56f7c..954ec68c 100644 --- a/workbooks/appdelivery_checklist.en_network_workbook_template.json +++ b/workbooks/appdelivery_checklist.en_network_workbook_template.json @@ -41,7 +41,7 @@ "dependsOn": [], "properties": { "displayName": "[parameters('workbookDisplayName')]", - "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Application Delivery Networking - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"d2797f6a-633c-487c-bbbc-e6e0ef7bdc78\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Load Balancer\",\n \"subTarget\": \"tab0\",\n \"preText\": \"Load Balancer\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"bf2db8b9-6cdc-42fd-9cb6-f4febd9d9140\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App Gateway\",\n \"subTarget\": \"tab1\",\n \"preText\": \"App Gateway\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Load Balancer\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## App Gateway\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", + "serializedData": "{\n \"version\": \"Notebook/1.0\",\n \"items\": [\n {\n \"type\": 9,\n \"content\": {\n \"version\": \"KqlParameterItem/1.0\",\n \"parameters\": [\n {\n \"id\": \"497a107e-dde8-433e-b263-35ac8e8f7834\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"Subscription\",\n \"type\": 6,\n \"multiSelect\": true,\n \"quote\": \"'\",\n \"delimiter\": \",\",\n \"typeSettings\": {\n \"additionalResourceOptions\": [\n \"value::all\"\n ],\n \"includeAll\": true,\n \"showDefault\": false\n },\n \"timeContext\": {\n \"durationMs\": 86400000\n },\n \"value\": [\n \"value::all\"\n ]\n },\n {\n \"id\": \"844e4f4e-df51-4e3c-8eaf-0dc78b92c721\",\n \"version\": \"KqlParameterItem/1.0\",\n \"name\": \"OnlyFailed\",\n \"label\": \"Only show failed\",\n \"type\": 2,\n \"typeSettings\": {\n \"additionalResourceOptions\": [],\n \"showDefault\": false\n },\n \"jsonData\": \"[\\r\\n { \\\"value\\\":true, \\\"label\\\":\\\"True\\\" },\\r\\n { \\\"value\\\":false, \\\"label\\\":\\\"False\\\", \\\"selected\\\":true }\\r\\n]\"\n }\n ],\n \"style\": \"pills\",\n \"queryType\": 0,\n \"resourceType\": \"microsoft.operationalinsights/workspaces\"\n },\n \"name\": \"WorkbookSelectors\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"If you set \\\"Only show failed\\\" to \\\"Yes\\\", the different queries will only show items that have failed their compliance checks.\",\n \"style\": \"info\"\n },\n \"name\": \"InfoBox\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Azure Application Delivery Networking - Network\\n\\n---\\n\\nThis workbook has been automatically generated out of the checklists in the [Azure Review Checklists repo](https://github.com/Azure/review-checklists). This repo contains best practices and recommendations around generic Landing Zones as well as specific services such as Azure Virtual Desktop, Azure Kubernetes Service or Azure VMware Solution, to name a few. This repository of best practices is curated by Azure engineers, but open to anybody to contribute.\\n\\nIf you see a problem in the queries that are part of this workbook, please open a Github issue [here](https://github.com/Azure/review-checklists/issues/new).\"\n },\n \"customWidth\": \"100\",\n \"name\": \"MarkdownHeader\"\n },\n {\n \"type\": 11,\n \"content\": {\n \"version\": \"LinkItem/1.0\",\n \"style\": \"tabs\",\n \"links\": [\n {\n \"id\": \"476f3f66-d6c1-4afc-97cf-e43fa43711a9\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"App Gateway\",\n \"subTarget\": \"tab0\",\n \"preText\": \"App Gateway\",\n \"style\": \"primary\"\n },\n {\n \"id\": \"4a68032b-c8a0-45dc-b535-68029ac69a00\",\n \"cellValue\": \"VisibleTab\",\n \"linkTarget\": \"parameter\",\n \"linkLabel\": \"Load Balancer\",\n \"subTarget\": \"tab1\",\n \"preText\": \"Load Balancer\",\n \"style\": \"primary\"\n }\n ]\n },\n \"name\": \"Tabs\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## App Gateway\"\n },\n \"name\": \"tab0title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using Application Gateway v2 SKU. Check [this link](https://learn.microsoft.com/azure/application-gateway/overview-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext0\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways' | project id, compliant = properties.sku.name in ('Standard_v2', 'WAF_v2') | project id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query0\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Your Application Gateways v2 should be deployed in subnets with IP prefixes equal or larger than /24. Check [this link](https://learn.microsoft.com/azure/application-gateway/configuration-infrastructure#size-of-the-subnet) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext2\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/applicationgateways' | extend subnetId = tostring(properties.gatewayIPConfigurations[0].properties.subnet.id) | project id, subnetId | join (resources | where type=='microsoft.network/virtualnetworks' | project id,subnets=properties.subnets | mv-expand subnets | mv-expand subnets.properties.addressPrefixes | project id, subnetId = tostring(subnets.id), prefix1 = subnets.properties.addressPrefix, prefix2 = subnets.properties.addressPrefixes | mv-expand prefix2 | extend prefix = iff(isnotnull(prefix1), prefix1, prefix2) | extend subnetPrefixLength = split(prefix, '/')[1])on subnetId | extend compliant = (subnetPrefixLength <= 24 or subnetPrefixLength == 64) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query2\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Configure autoscaling with a minimum amount of instances of two. Check [this link](https://learn.microsoft.com/azure/application-gateway/application-gateway-autoscaling-zone-redundant) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext3\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(properties.autoscaleConfiguration) and properties.autoscaleConfiguration.minCapacity >= 2) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query3\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Deploy Application Gateway across Availability Zones. Check [this link](https://learn.microsoft.com/azure/reliability/migrate-app-gateway-v2) for further information.. [This training](https://learn.microsoft.com/learn/paths/secure-application-delivery/) can help to educate yourself on this.\"\n },\n \"name\": \"querytext4\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationGateways' | extend compliant = (isnotnull(zones) and array_length(zones) > 1) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query4\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Enable the Azure Application Gateway WAF bot protection rule set. The bot rules detect good and bad bots. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/bot-protection) for further information.\"\n },\n \"name\": \"querytext6\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | mv-expand properties.managedRules.managedRuleSets | project id, rulesettype = properties_managedRules_managedRuleSets.ruleSetType | extend compliant1 = (rulesettype == 'Microsoft_BotManagerRuleSet') | project id, compliant1 | summarize compliant = max(compliant1) by id | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query6\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure if request body inspection feature is enabled in Azure Application Gateway WAF policy. Check [this link](https://learn.microsoft.com/azure/web-application-firewall/ag/application-gateway-waf-request-size-limits#request-body-inspection) for further information.\"\n },\n \"name\": \"querytext7\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type =~ 'microsoft.network/applicationgatewaywebapplicationfirewallpolicies' | extend compliant = (properties['policySettings']['requestBodyCheck'] == 'true' and properties['policySettings']['state'] =~ 'Enabled') | distinct id, name, compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query7\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"You should encrypt traffic to the backend servers. Check [this link](https://learn.microsoft.com/azure/application-gateway/ssl-overview) for further information.\"\n },\n \"name\": \"querytext8\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/applicationgateways'| extend compliant = (properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443') |where properties['backendHttpSettingsCollection'][0]['properties']['port'] =~ '443'|distinct id,name,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query8\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab0\"\n },\n \"name\": \"tab0\"\n },\n {\n \"type\": 12,\n \"content\": {\n \"version\": \"NotebookGroup/1.0\",\n \"groupType\": \"editable\",\n \"items\": [\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"## Load Balancer\"\n },\n \"name\": \"tab1title\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Ensure you are using the Standard SKU for your Azure Load Balancers. Check [this link](https://learn.microsoft.com/azure/load-balancer/load-balancer-overview) for further information.\"\n },\n \"name\": \"querytext1\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type == 'microsoft.network/loadbalancers' | project id, compliant=(tolower(sku.name) == 'standard') | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query1\"\n },\n {\n \"type\": 1,\n \"content\": {\n \"json\": \"Use Azure NAT Gateway instead of Load Balancer outbound rules for better SNAT scalability. Check [this link](https://learn.microsoft.com/azure/nat-gateway/nat-overview#outbound-connectivity) for further information.\"\n },\n \"name\": \"querytext5\"\n },\n {\n \"type\": 3,\n \"content\": {\n \"version\": \"KqlItem/1.0\",\n \"query\": \"resources | where type=='microsoft.network/loadbalancers' | extend countOutRules=array_length(properties.outboundRules) | extend compliant = (countOutRules == 0) | distinct id,compliant | extend onlyFailed = {OnlyFailed:label} | where compliant == 0 or not (onlyFailed == 1) | project-away onlyFailed\",\n \"size\": 4,\n \"queryType\": 1,\n \"resourceType\": \"microsoft.resourcegraph/resources\",\n \"crossComponentResources\": [\n \"{Subscription}\"\n ],\n \"gridSettings\": {\n \"formatters\": [\n {\n \"columnMatch\": \"id\",\n \"formatter\": 0,\n \"numberFormat\": {\n \"unit\": 0,\n \"options\": {\n \"style\": \"decimal\"\n }\n }\n },\n {\n \"columnMatch\": \"compliant\",\n \"formatter\": 18,\n \"formatOptions\": {\n \"thresholdsOptions\": \"icons\",\n \"thresholdsGrid\": [\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"1\",\n \"representation\": \"success\",\n \"text\": \"Success\"\n },\n {\n \"operator\": \"==\",\n \"thresholdValue\": \"0\",\n \"representation\": \"failed\",\n \"text\": \"Failed\"\n },\n {\n \"operator\": \"Default\",\n \"thresholdValue\": null,\n \"representation\": \"unknown\",\n \"text\": \"Unknown\"\n }\n ]\n }\n }\n ]\n }\n },\n \"name\": \"query5\"\n }\n ]\n },\n \"conditionalVisibility\": {\n \"parameterName\": \"VisibleTab\",\n \"comparison\": \"isEqualTo\",\n \"value\": \"tab1\"\n },\n \"name\": \"tab1\"\n }\n ],\n \"$schema\": \"https://github.com/Microsoft/Application-Insights-Workbooks/blob/master/schema/workbook.json\"\n}", "version": "1.0", "sourceId": "[parameters('workbookSourceId')]", "category": "[parameters('workbookType')]"