Active findings
36Built-in scenario
azure/sample_azure_nightmare_plan.jsonAzure Nightmare Plan Demo
Analyzed sample_azure_nightmare_plan.json with 27 normalized resources and 5 trust boundaries.
Trust boundaries
5Resources
27Observations
3Analysis coverage
Audit trail for this run
Resource coverage
- Provider resources considered
- 27
- Normalized resources
- 27
No unsupported Azure resource types were encountered.
Rule coverage
- Registered rules
- 94
- Disabled rules
- 0
- azure-public-compute-broad-ingress2
- azure-nsg-flow-logs-not-configured3
- azure-storage-container-public-access3
- azure-storage-account-nested-public-access-enabled2
- azure-storage-account-shared-key-enabled2
- azure-storage-account-minimum-tls-below-1-22
- azure-storage-account-public-network-unrestricted2
- azure-storage-account-missing-private-endpoint2
- azure-key-vault-public-network-access1
- azure-key-vault-missing-private-endpoint1
- azure-key-vault-purge-protection-disabled1
- azure-managed-identity-broad-rbac1
- azure-public-workload-sensitive-resource-access1
- azure-diagnostic-settings-missing4
- azure-aks-api-server-public-unrestricted1
- azure-aks-local-accounts-not-disabled1
- azure-aks-rbac-posture-weak1
- azure-aks-network-policy-missing1
- azure-aks-workload-identity-not-enabled1
- azure-aks-key-management-service-not-configured1
- azure-aks-monitoring-agent-not-enabled1
- azure-aks-defender-not-enabled1
- azure-aks-azure-policy-not-enabled1
Findings
Severity bands
High
7AKS control plane is public without narrow authorized IP ranges
azure-aks-api-server-public-unrestrictedazurerm_kubernetes_cluster.platform has AKS private cluster mode disabled and does not define narrow authorized IP ranges for the Kubernetes API server. The control plane is publicly reachable without a reviewed source range restriction.
- Category
- Elevation of Privilege
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- control plane posture: private_cluster_state=disabled; authorized_ip_ranges_state=not_configured; api_server_vnet_integration_state=unknown
Azure Storage account permits Shared Key authorization
azure-storage-account-shared-key-enabledazurerm_storage_account.assets permits Shared Key authorization. Account keys provide broad data-plane authority and are harder to constrain and attribute than Microsoft Entra ID identities.
- Category
- Elevation of Privilege
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.assets
Evidence
- authorization posture: shared_access_key_enabled is true
Azure Storage account permits Shared Key authorization
azure-storage-account-shared-key-enabledazurerm_storage_account.logs permits Shared Key authorization. Account keys provide broad data-plane authority and are harder to constrain and attribute than Microsoft Entra ID identities.
- Category
- Elevation of Privilege
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.logs
Evidence
- authorization posture: shared_access_key_enabled is true
Azure Storage account permits nested public blob access
azure-storage-account-nested-public-access-enabledazurerm_storage_account.assets permits containers and blobs to opt into anonymous public access. This account-level setting allows a subordinate container configuration to expose stored data.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.assets
Evidence
- public access posture: allow_nested_items_to_be_public is true
Azure Storage account permits nested public blob access
azure-storage-account-nested-public-access-enabledazurerm_storage_account.logs permits containers and blobs to opt into anonymous public access. This account-level setting allows a subordinate container configuration to expose stored data.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.logs
Evidence
- public access posture: allow_nested_items_to_be_public is true
Azure managed identity has broad RBAC authority
azure-managed-identity-broad-rbacazurerm_user_assigned_identity.deploy has Azure role assignments with broad scope or high-impact built-in roles. These grants expand what the managed identity can do if the workload or deployment path using it is compromised.
- Category
- Elevation of Privilege
- Boundary
- not-applicable
- Resources
- azurerm_user_assigned_identity.deploy, azurerm_role_assignment.storage_owner, azurerm_storage_account.logs
Evidence
- managed identity: address=azurerm_user_assigned_identity.deploy; identity_type=UserAssigned; principal_id=11111111-1111-1111-1111-111111111111; client_id=22222222-2222-2222-2222-222222222222
- role assignments: source=azurerm_role_assignment.storage_owner; role=Storage Blob Data Owner; scope=azurerm_storage_account.logs.id; scope_kind=resource; target=azurerm_storage_account.logs; signals=broad_builtin_role,sensitive_resource_scope
- breadth signals: broad_builtin_role; sensitive_resource_scope
- privileged access: grant_1=role=Storage Blob Data Owner; categories=data-admin; scope_kind=resource; confidence=high
- privilege categories: data-admin
Internet-exposed Azure workload can access sensitive resources
azure-public-workload-sensitive-resource-accessazurerm_user_assigned_identity.deploy is usable by an internet-exposed Azure workload and has a deterministic role assignment to a sensitive Azure resource. This creates a clear public workload to sensitive resource path if the workload identity is abused.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_linux_virtual_machine.web
- Resources
- azurerm_linux_virtual_machine.web, azurerm_user_assigned_identity.deploy, azurerm_role_assignment.storage_owner, azurerm_storage_account.logs
Evidence
- public workloads: address=azurerm_linux_virtual_machine.web; public_exposure=true; public_exposure_reasons=virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress
- managed identity: address=azurerm_user_assigned_identity.deploy; identity_type=UserAssigned; principal_id=11111111-1111-1111-1111-111111111111; client_id=22222222-2222-2222-2222-222222222222
- sensitive resource assignments: source=azurerm_role_assignment.storage_owner; role=Storage Blob Data Owner; scope=azurerm_storage_account.logs.id; scope_kind=resource; target=azurerm_storage_account.logs; signals=broad_builtin_role,sensitive_resource_scope
Medium
24AKS Defender coverage is not enabled
azure-aks-defender-not-enabledazurerm_kubernetes_cluster.platform does not show deterministic Microsoft Defender for Containers coverage. Missing Defender signals can reduce runtime threat detection and security recommendations for AKS workloads.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- defender posture: defender_state=not_configured
AKS Key Management Service is not configured
azure-aks-key-management-service-not-configuredazurerm_kubernetes_cluster.platform does not show deterministic AKS Key Management Service configuration with a Key Vault key. Kubernetes secrets may not have customer-controlled encryption key ownership represented in the Terraform plan.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- secret encryption posture: key_management_service_state=not_configured; key_vault_key_id is not represented in planned values
AKS monitoring agent is not enabled
azure-aks-monitoring-agent-not-enabledazurerm_kubernetes_cluster.platform does not show deterministic AKS monitoring through the OMS agent and Log Analytics. Missing cluster telemetry can limit detection and investigation of control-plane and workload activity.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- monitoring posture: oms_agent_state=not_configured; log_analytics_workspace_id is not represented in planned values
Azure Key Vault allows unrestricted public network access
azure-key-vault-public-network-accessazurerm_key_vault.application enables its public endpoint with an effective `Allow` network ACL default action. Network reachability does not itself grant data access, but it exposes the sensitive service endpoint to internet clients.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_key_vault.application
- Resources
- azurerm_key_vault.application
Evidence
- network exposure: public_network_access_enabled is true; effective network_acls.default_action is Allow; network exposure is evaluated separately from identity authorization
Azure Key Vault lacks resolved private endpoint coverage
azure-key-vault-missing-private-endpointazurerm_key_vault.application does not have a resolved private endpoint and may allow public Key Vault data-plane access depending on firewall settings. This finding does not claim secret exposure; identity authorization is evaluated separately.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_key_vault.application
Evidence
- target resource: address=azurerm_key_vault.application; type=azurerm_key_vault
- public network fallback: public_network_fallback_state=enabled; public_network_access_enabled is true
- private endpoint coverage: no resolved private endpoint targets this resource
- network acl posture: effective default_action is Allow
Azure Key Vault purge protection is disabled
azure-key-vault-purge-protection-disabledazurerm_key_vault.application does not enable purge protection. A principal with sufficient deletion authority could permanently remove vault contents during the retention window.
- Category
- Tampering
- Boundary
- not-applicable
- Resources
- azurerm_key_vault.application
Evidence
- recovery posture: purge_protection_enabled is false
Azure Network Security Group lacks flow-log coverage
azure-nsg-flow-logs-not-configuredazurerm_network_security_group.web_subnet does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_network_security_group.web_subnet
Evidence
- target network security group: address=azurerm_network_security_group.web_subnet; resource_type=azurerm_network_security_group; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-subnet; name=web-subnet
- flow log coverage: target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/web-subnet; target_nsg_identifier=azurerm_network_security_group.web_subnet; target_nsg_identifier=azurerm_network_security_group.web_subnet.id; target_nsg_identifier=web-subnet; resolved_nsg_flow_log_count=0; azurerm_network_watcher_flow_log resources are not modeled
Azure Network Security Group lacks flow-log coverage
azure-nsg-flow-logs-not-configuredazurerm_network_security_group.web_nic does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_network_security_group.web_nic
Evidence
- target network security group: address=azurerm_network_security_group.web_nic; resource_type=azurerm_network_security_group; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-nic; name=web-nic
- flow log coverage: target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/web-nic; target_nsg_identifier=azurerm_network_security_group.web_nic; target_nsg_identifier=azurerm_network_security_group.web_nic.id; target_nsg_identifier=web-nic; resolved_nsg_flow_log_count=0; azurerm_network_watcher_flow_log resources are not modeled
Azure Network Security Group lacks flow-log coverage
azure-nsg-flow-logs-not-configuredazurerm_network_security_group.admin_nic does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_network_security_group.admin_nic
Evidence
- target network security group: address=azurerm_network_security_group.admin_nic; resource_type=azurerm_network_security_group; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/admin-nic; name=admin-nic
- flow log coverage: target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/admin-nic; target_nsg_identifier=admin-nic; target_nsg_identifier=azurerm_network_security_group.admin_nic; target_nsg_identifier=azurerm_network_security_group.admin_nic.id; resolved_nsg_flow_log_count=0; azurerm_network_watcher_flow_log resources are not modeled
Azure Storage account allows TLS below 1.2
azure-storage-account-minimum-tls-below-1-2azurerm_storage_account.assets accepts `TLS1_1` as its minimum protocol version. Deprecated TLS versions weaken transport protection for storage data-plane requests.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.assets
Evidence
- transport posture: min_tls_version is TLS1_1
Azure Storage account allows TLS below 1.2
azure-storage-account-minimum-tls-below-1-2azurerm_storage_account.logs accepts `TLS1_0` as its minimum protocol version. Deprecated TLS versions weaken transport protection for storage data-plane requests.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.logs
Evidence
- transport posture: min_tls_version is TLS1_0
Azure Storage account allows unrestricted public network access
azure-storage-account-public-network-unrestrictedazurerm_storage_account.assets enables its public network endpoint with an effective `Allow` default action. Storage data-plane endpoints are reachable without a default-deny network boundary.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_storage_account.assets
- Resources
- azurerm_storage_account.assets
Evidence
- network posture: public_network_access_enabled is true; effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.assets
Azure Storage account allows unrestricted public network access
azure-storage-account-public-network-unrestrictedazurerm_storage_account.logs enables its public network endpoint with an effective `Allow` default action. Storage data-plane endpoints are reachable without a default-deny network boundary.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_storage_account.logs
- Resources
- azurerm_storage_account.logs
Evidence
- network posture: public_network_access_enabled is true; effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.logs
Azure Storage account lacks resolved private endpoint coverage
azure-storage-account-missing-private-endpointazurerm_storage_account.assets does not have a resolved private endpoint and may remain reachable through public Azure Storage data-plane endpoints. Network rules can reduce exposure, but they are not equivalent to private-endpoint-only access unless public network fallback is disabled.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.assets
Evidence
- target resource: address=azurerm_storage_account.assets; type=azurerm_storage_account
- public network fallback: public_network_fallback_state=enabled; public_network_access_enabled is true
- private endpoint coverage: no resolved private endpoint targets this resource
- network acl posture: effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.assets
Azure Storage account lacks resolved private endpoint coverage
azure-storage-account-missing-private-endpointazurerm_storage_account.logs does not have a resolved private endpoint and may remain reachable through public Azure Storage data-plane endpoints. Network rules can reduce exposure, but they are not equivalent to private-endpoint-only access unless public network fallback is disabled.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.logs
Evidence
- target resource: address=azurerm_storage_account.logs; type=azurerm_storage_account
- public network fallback: public_network_fallback_state=enabled; public_network_access_enabled is true
- private endpoint coverage: no resolved private endpoint targets this resource
- network acl posture: effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.logs
Azure Storage container is publicly accessible
azure-storage-container-public-accessazurerm_storage_container.public_assets permits anonymous `blob` access through a storage account that allows nested public access and unrestricted public network reachability.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_storage_account.assets
- Resources
- azurerm_storage_account.assets, azurerm_storage_container.public_assets
Evidence
- public exposure reasons: container_access_type is blob; azurerm_storage_account.assets allows nested items to be public; azurerm_storage_account.assets is reachable through its public network endpoint
Azure Storage container is publicly accessible
azure-storage-container-public-accessazurerm_storage_container.public_logs permits anonymous `container` access through a storage account that allows nested public access and unrestricted public network reachability.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_storage_account.logs
- Resources
- azurerm_storage_account.logs, azurerm_storage_container.public_logs
Evidence
- public exposure reasons: container_access_type is container; azurerm_storage_account.logs allows nested items to be public; azurerm_storage_account.logs is reachable through its public network endpoint
Azure Storage container is publicly accessible
azure-storage-container-public-accessazurerm_storage_container.public_backups permits anonymous `blob` access through a storage account that allows nested public access and unrestricted public network reachability.
- Category
- Information Disclosure
- Boundary
- internet-to-service:internet->azurerm_storage_account.logs
- Resources
- azurerm_storage_account.logs, azurerm_storage_container.public_backups
Evidence
- public exposure reasons: container_access_type is blob; azurerm_storage_account.logs allows nested items to be public; azurerm_storage_account.logs is reachable through its public network endpoint
Azure resource lacks diagnostic settings
azure-diagnostic-settings-missingazurerm_storage_account.assets has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.assets
Evidence
- target resource: address=azurerm_storage_account.assets; type=azurerm_storage_account; name=tfstridepublicassets; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepublicassets
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
Azure resource lacks diagnostic settings
azure-diagnostic-settings-missingazurerm_storage_account.logs has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_storage_account.logs
Evidence
- target resource: address=azurerm_storage_account.logs; type=azurerm_storage_account; name=tfstridepubliclogs; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepubliclogs
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
Azure resource lacks diagnostic settings
azure-diagnostic-settings-missingazurerm_kubernetes_cluster.platform has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster; name=tfstride-platform; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.ContainerService/managedClusters/tfstride-platform
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
Azure resource lacks diagnostic settings
azure-diagnostic-settings-missingazurerm_key_vault.application has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Category
- Repudiation
- Boundary
- not-applicable
- Resources
- azurerm_key_vault.application
Evidence
- target resource: address=azurerm_key_vault.application; type=azurerm_key_vault; name=tfstride-application; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.KeyVault/vaults/tfstride-application
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
Internet-exposed Azure virtual machine permits broad ingress
azure-public-compute-broad-ingressazurerm_linux_virtual_machine.web has a public-IP path and the effective Azure NSG decisions across its subnet and network interface permit administrative access or all ports from internet sources. This exposes the guest to direct probing and credential attacks.
- Category
- Spoofing
- Boundary
- internet-to-service:internet->azurerm_linux_virtual_machine.web
- Resources
- azurerm_linux_virtual_machine.web, azurerm_network_interface.web, azurerm_public_ip.web, azurerm_network_security_group.web_nic, azurerm_network_security_group.web_subnet
Evidence
- public ip path: azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_public_ip.web (203.0.113.10)
- network security path: azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_network_security_group.web_nic; azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_network_security_group.web_subnet
- network security rules: azurerm_network_security_group.web_nic rule allow-ssh priority 200 allows tcp 22 from Internet; azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet
- public exposure reasons: virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress
Internet-exposed Azure virtual machine permits broad ingress
azure-public-compute-broad-ingressazurerm_windows_virtual_machine.admin has a public-IP path and the effective Azure NSG decisions across its subnet and network interface permit administrative access or all ports from internet sources. This exposes the guest to direct probing and credential attacks.
- Category
- Spoofing
- Boundary
- internet-to-service:internet->azurerm_windows_virtual_machine.admin
- Resources
- azurerm_windows_virtual_machine.admin, azurerm_network_interface.admin, azurerm_public_ip.admin, azurerm_network_security_group.admin_nic, azurerm_network_security_group.web_subnet
Evidence
- public ip path: azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_public_ip.admin (203.0.113.20)
- network security path: azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_network_security_group.admin_nic; azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_network_security_group.web_subnet
- network security rules: azurerm_network_security_group.admin_nic rule allow-rdp priority 200 allows tcp 3389 from Internet; azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet
- public exposure reasons: virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress
Low
5AKS Azure Policy add-on is not enabled
azure-aks-azure-policy-not-enabledazurerm_kubernetes_cluster.platform does not deterministically enable the Azure Policy add-on. Without the add-on, Kubernetes policy and governance controls may rely on external review instead of in-cluster policy enforcement.
- Category
- Tampering
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- azure policy posture: azure_policy_state=unknown
AKS RBAC posture is weak or not deterministic
azure-aks-rbac-posture-weakazurerm_kubernetes_cluster.platform has weak or non-deterministic AKS RBAC posture. Kubernetes RBAC should be explicitly enabled, and Azure RBAC integration should not be disabled when the Azure Active Directory RBAC block is represented in the Terraform plan.
- Category
- Elevation of Privilege
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- rbac posture: kubernetes_rbac_state=unknown; aad_rbac_state=not_configured; aad_managed_state=unknown; aad_azure_rbac_state=unknown; kubernetes RBAC state is unknown
AKS local accounts are not disabled
azure-aks-local-accounts-not-disabledazurerm_kubernetes_cluster.platform does not deterministically disable AKS local accounts. Local cluster accounts can weaken centralized Microsoft Entra ID identity, auditing, and access control if they remain enabled.
- Category
- Spoofing
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- authentication posture: local_account_state=unknown
AKS network policy is not configured
azure-aks-network-policy-missingazurerm_kubernetes_cluster.platform does not have deterministic AKS network policy configured. Without a pod network policy provider, Kubernetes workloads have weaker pod-level traffic isolation and lateral-movement controls.
- Category
- Information Disclosure
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- network policy posture: network_policy_state=unknown; network_policy is not represented in planned values
AKS workload identity is not fully enabled
azure-aks-workload-identity-not-enabledazurerm_kubernetes_cluster.platform does not deterministically enable AKS workload identity and its OIDC issuer. Pods may need to rely on broader node credentials, static secrets, or less auditable identity paths for Azure resource access.
- Category
- Elevation of Privilege
- Boundary
- not-applicable
- Resources
- azurerm_kubernetes_cluster.platform
Evidence
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- workload identity posture: oidc_issuer_state=unknown; workload_identity_state=unknown
Observations
Controls and mitigating signals
Azure managed identity principal is modeled
azurerm_linux_virtual_machine.web exposes a `UserAssigned` managed identity principal. Role assignments are connected only when principal IDs are known in the Terraform plan.
Azure managed identity principal is modeled
azurerm_user_assigned_identity.deploy exposes a `UserAssigned` managed identity principal. Role assignments are connected only when principal IDs are known in the Terraform plan.
Azure managed identity role assignment is connected
azurerm_user_assigned_identity.deploy has Azure role assignments whose `principal_id` matches this managed identity. Scope breadth is reported separately from any downstream exposure rule.
Trust boundaries
Crossings that drive the model
internet-to-service
internet -> azurerm_key_vault.application
The resource is directly reachable or intentionally exposed to unauthenticated network clients.
internet-to-service
internet -> azurerm_linux_virtual_machine.web
The resource is directly reachable or intentionally exposed to unauthenticated network clients.
internet-to-service
internet -> azurerm_storage_account.assets
The resource is directly reachable or intentionally exposed to unauthenticated network clients.
internet-to-service
internet -> azurerm_storage_account.logs
The resource is directly reachable or intentionally exposed to unauthenticated network clients.
internet-to-service
internet -> azurerm_windows_virtual_machine.admin
The resource is directly reachable or intentionally exposed to unauthenticated network clients.
Raw outputs
Stable contract and markdown
JSON report
{
"kind": "tfstride-report",
"version": "1.1",
"tool": {
"name": "tfstride",
"version": "0.4.23"
},
"title": "Azure Nightmare Plan Demo",
"analyzed_file": "sample_azure_nightmare_plan.json",
"analyzed_path": "sample_azure_nightmare_plan.json",
"summary": {
"normalized_resources": 27,
"unsupported_resources": 0,
"trust_boundaries": 5,
"active_findings": 36,
"total_findings": 36,
"suppressed_findings": 0,
"baselined_findings": 0,
"severity_counts": {
"high": 7,
"medium": 24,
"low": 5
}
},
"filtering": {
"total_findings": 36,
"active_findings": 36,
"suppressed_findings": 0,
"baselined_findings": 0,
"suppressions_path": null,
"baseline_path": null
},
"analysis_coverage": {
"resources": {
"total_resources": 27,
"provider_resources": 27,
"normalized_resources": 27,
"unsupported_resources": 0,
"unsupported_resource_types": {}
},
"rules": {
"registered_rule_count": 94,
"enabled_rules": [
"azure-public-compute-broad-ingress",
"azure-load-balancer-public-frontend",
"azure-application-gateway-public-listener",
"azure-public-application-gateway-waf-missing",
"azure-nsg-flow-logs-not-configured",
"azure-nsg-flow-log-disabled",
"azure-nsg-flow-log-destination-missing",
"azure-nsg-flow-log-retention-insufficient",
"azure-storage-container-public-access",
"azure-storage-account-nested-public-access-enabled",
"azure-storage-account-shared-key-enabled",
"azure-storage-account-minimum-tls-below-1-2",
"azure-storage-account-public-network-unrestricted",
"azure-storage-account-customer-managed-key-missing",
"azure-storage-account-infrastructure-encryption-not-enabled",
"azure-storage-account-blob-versioning-disabled",
"azure-storage-account-blob-soft-delete-insufficient",
"azure-storage-account-container-soft-delete-insufficient",
"azure-storage-account-point-in-time-restore-missing",
"azure-storage-account-missing-private-endpoint",
"azure-service-bus-public-network-access-not-disabled",
"azure-service-bus-minimum-tls-below-1-2",
"azure-service-bus-minimum-tls-unknown",
"azure-service-bus-local-auth-enabled",
"azure-service-bus-customer-managed-key-missing",
"azure-service-bus-missing-private-endpoint",
"azure-container-registry-public-network-access-not-disabled",
"azure-container-registry-admin-account-enabled",
"azure-container-registry-anonymous-pull-enabled",
"azure-container-registry-customer-managed-key-missing",
"azure-container-registry-missing-private-endpoint",
"azure-key-vault-public-network-access",
"azure-key-vault-missing-private-endpoint",
"azure-key-vault-privileged-access",
"azure-key-vault-purge-protection-disabled",
"azure-key-vault-secret-certificate-lifecycle-incomplete",
"azure-key-vault-key-strength-weak",
"azure-key-vault-key-rotation-policy-incomplete",
"azure-custom-role-wildcard-management-plane",
"azure-custom-role-authorization-management",
"azure-custom-role-broad-management-plane",
"azure-custom-role-broad-data-plane",
"azure-custom-role-subscription-assignable-scope",
"azure-custom-role-assignment-blast-radius",
"azure-rbac-privileged-assignment",
"azure-managed-identity-broad-rbac",
"azure-federated-identity-privileged-access",
"azure-public-workload-sensitive-resource-access",
"azure-app-service-public-network-access-not-disabled",
"azure-app-service-platform-authentication-disabled",
"azure-app-service-anonymous-platform-access-allowed",
"azure-app-service-minimum-tls-below-1-2",
"azure-app-service-minimum-tls-unknown",
"azure-app-service-managed-identity-missing",
"azure-app-service-vnet-integration-missing",
"azure-app-service-access-restrictions-not-default-deny",
"azure-app-service-broad-access-restriction-allow",
"azure-app-service-scm-access-unrestricted",
"azure-app-service-image-not-digest-pinned",
"azure-app-service-can-modify-image-repository",
"azure-public-app-service-storage-mutation-access",
"azure-public-app-service-service-bus-mutation-access",
"azure-app-service-sensitive-app-setting-inline",
"azure-app-service-key-vault-reference-identity-not-configured",
"azure-app-service-key-vault-secret-access-overprivileged",
"azure-diagnostic-settings-missing",
"azure-diagnostic-setting-no-log-destination",
"azure-diagnostic-setting-audit-logs-incomplete",
"azure-defender-pricing-tier-not-standard",
"azure-security-center-auto-provisioning-disabled",
"azure-aks-api-server-public-unrestricted",
"azure-aks-private-cluster-not-enabled",
"azure-aks-local-accounts-not-disabled",
"azure-aks-rbac-posture-weak",
"azure-aks-network-policy-missing",
"azure-aks-workload-identity-not-enabled",
"azure-aks-key-management-service-not-configured",
"azure-aks-monitoring-agent-not-enabled",
"azure-aks-defender-not-enabled",
"azure-aks-azure-policy-not-enabled",
"azure-sql-public-network-access-enabled",
"azure-sql-missing-private-endpoint",
"azure-sql-firewall-broad-public-access",
"azure-sql-minimum-tls-below-1-2",
"azure-sql-security-alert-policy-disabled",
"azure-sql-short-term-backup-retention-insufficient",
"azure-sql-long-term-backup-retention-not-configured",
"azure-sql-backup-geo-redundancy-not-enabled",
"azure-private-endpoint-public-fallback",
"azure-private-endpoint-dns-posture-incomplete",
"azure-postgresql-public-network-access-enabled",
"azure-postgresql-firewall-broad-public-access",
"azure-postgresql-weak-tls-or-ssl",
"azure-postgresql-geo-backup-disabled"
],
"disabled_rules": [],
"severity_overrides": {},
"finding_counts_by_rule": {
"azure-public-compute-broad-ingress": 2,
"azure-load-balancer-public-frontend": 0,
"azure-application-gateway-public-listener": 0,
"azure-public-application-gateway-waf-missing": 0,
"azure-nsg-flow-logs-not-configured": 3,
"azure-nsg-flow-log-disabled": 0,
"azure-nsg-flow-log-destination-missing": 0,
"azure-nsg-flow-log-retention-insufficient": 0,
"azure-storage-container-public-access": 3,
"azure-storage-account-nested-public-access-enabled": 2,
"azure-storage-account-shared-key-enabled": 2,
"azure-storage-account-minimum-tls-below-1-2": 2,
"azure-storage-account-public-network-unrestricted": 2,
"azure-storage-account-customer-managed-key-missing": 0,
"azure-storage-account-infrastructure-encryption-not-enabled": 0,
"azure-storage-account-blob-versioning-disabled": 0,
"azure-storage-account-blob-soft-delete-insufficient": 0,
"azure-storage-account-container-soft-delete-insufficient": 0,
"azure-storage-account-point-in-time-restore-missing": 0,
"azure-storage-account-missing-private-endpoint": 2,
"azure-service-bus-public-network-access-not-disabled": 0,
"azure-service-bus-minimum-tls-below-1-2": 0,
"azure-service-bus-minimum-tls-unknown": 0,
"azure-service-bus-local-auth-enabled": 0,
"azure-service-bus-customer-managed-key-missing": 0,
"azure-service-bus-missing-private-endpoint": 0,
"azure-container-registry-public-network-access-not-disabled": 0,
"azure-container-registry-admin-account-enabled": 0,
"azure-container-registry-anonymous-pull-enabled": 0,
"azure-container-registry-customer-managed-key-missing": 0,
"azure-container-registry-missing-private-endpoint": 0,
"azure-key-vault-public-network-access": 1,
"azure-key-vault-missing-private-endpoint": 1,
"azure-key-vault-privileged-access": 0,
"azure-key-vault-purge-protection-disabled": 1,
"azure-key-vault-secret-certificate-lifecycle-incomplete": 0,
"azure-key-vault-key-strength-weak": 0,
"azure-key-vault-key-rotation-policy-incomplete": 0,
"azure-custom-role-wildcard-management-plane": 0,
"azure-custom-role-authorization-management": 0,
"azure-custom-role-broad-management-plane": 0,
"azure-custom-role-broad-data-plane": 0,
"azure-custom-role-subscription-assignable-scope": 0,
"azure-custom-role-assignment-blast-radius": 0,
"azure-rbac-privileged-assignment": 0,
"azure-managed-identity-broad-rbac": 1,
"azure-federated-identity-privileged-access": 0,
"azure-public-workload-sensitive-resource-access": 1,
"azure-app-service-public-network-access-not-disabled": 0,
"azure-app-service-platform-authentication-disabled": 0,
"azure-app-service-anonymous-platform-access-allowed": 0,
"azure-app-service-minimum-tls-below-1-2": 0,
"azure-app-service-minimum-tls-unknown": 0,
"azure-app-service-managed-identity-missing": 0,
"azure-app-service-vnet-integration-missing": 0,
"azure-app-service-access-restrictions-not-default-deny": 0,
"azure-app-service-broad-access-restriction-allow": 0,
"azure-app-service-scm-access-unrestricted": 0,
"azure-app-service-image-not-digest-pinned": 0,
"azure-app-service-can-modify-image-repository": 0,
"azure-public-app-service-storage-mutation-access": 0,
"azure-public-app-service-service-bus-mutation-access": 0,
"azure-app-service-sensitive-app-setting-inline": 0,
"azure-app-service-key-vault-reference-identity-not-configured": 0,
"azure-app-service-key-vault-secret-access-overprivileged": 0,
"azure-diagnostic-settings-missing": 4,
"azure-diagnostic-setting-no-log-destination": 0,
"azure-diagnostic-setting-audit-logs-incomplete": 0,
"azure-defender-pricing-tier-not-standard": 0,
"azure-security-center-auto-provisioning-disabled": 0,
"azure-aks-api-server-public-unrestricted": 1,
"azure-aks-private-cluster-not-enabled": 0,
"azure-aks-local-accounts-not-disabled": 1,
"azure-aks-rbac-posture-weak": 1,
"azure-aks-network-policy-missing": 1,
"azure-aks-workload-identity-not-enabled": 1,
"azure-aks-key-management-service-not-configured": 1,
"azure-aks-monitoring-agent-not-enabled": 1,
"azure-aks-defender-not-enabled": 1,
"azure-aks-azure-policy-not-enabled": 1,
"azure-sql-public-network-access-enabled": 0,
"azure-sql-missing-private-endpoint": 0,
"azure-sql-firewall-broad-public-access": 0,
"azure-sql-minimum-tls-below-1-2": 0,
"azure-sql-security-alert-policy-disabled": 0,
"azure-sql-short-term-backup-retention-insufficient": 0,
"azure-sql-long-term-backup-retention-not-configured": 0,
"azure-sql-backup-geo-redundancy-not-enabled": 0,
"azure-private-endpoint-public-fallback": 0,
"azure-private-endpoint-dns-posture-incomplete": 0,
"azure-postgresql-public-network-access-enabled": 0,
"azure-postgresql-firewall-broad-public-access": 0,
"azure-postgresql-weak-tls-or-ssl": 0,
"azure-postgresql-geo-backup-disabled": 0
}
},
"references": {
"unresolved_reference_count": 0,
"unresolved_references": []
}
},
"inventory": {
"provider": "azure",
"unsupported_resources": [],
"metadata": {
"supported_resource_types": [
"azurerm_advanced_threat_protection",
"azurerm_application_gateway",
"azurerm_container_registry",
"azurerm_federated_identity_credential",
"azurerm_function_app",
"azurerm_key_vault",
"azurerm_key_vault_access_policy",
"azurerm_key_vault_certificate",
"azurerm_key_vault_key",
"azurerm_key_vault_secret",
"azurerm_kubernetes_cluster",
"azurerm_lb",
"azurerm_linux_function_app",
"azurerm_linux_virtual_machine",
"azurerm_linux_web_app",
"azurerm_monitor_diagnostic_setting",
"azurerm_mssql_database",
"azurerm_mssql_firewall_rule",
"azurerm_mssql_server",
"azurerm_mssql_server_security_alert_policy",
"azurerm_mssql_virtual_network_rule",
"azurerm_network_interface",
"azurerm_network_interface_security_group_association",
"azurerm_network_security_group",
"azurerm_network_security_rule",
"azurerm_network_watcher_flow_log",
"azurerm_postgresql_flexible_server",
"azurerm_postgresql_flexible_server_configuration",
"azurerm_postgresql_flexible_server_database",
"azurerm_postgresql_flexible_server_firewall_rule",
"azurerm_private_dns_zone",
"azurerm_private_dns_zone_virtual_network_link",
"azurerm_private_endpoint",
"azurerm_public_ip",
"azurerm_role_assignment",
"azurerm_role_definition",
"azurerm_security_center_auto_provisioning",
"azurerm_security_center_contact",
"azurerm_security_center_setting",
"azurerm_security_center_subscription_pricing",
"azurerm_security_center_workspace",
"azurerm_servicebus_namespace",
"azurerm_servicebus_namespace_customer_managed_key",
"azurerm_servicebus_namespace_network_rule_set",
"azurerm_servicebus_queue",
"azurerm_servicebus_subscription",
"azurerm_servicebus_topic",
"azurerm_storage_account",
"azurerm_storage_account_network_rules",
"azurerm_storage_container",
"azurerm_subnet",
"azurerm_subnet_network_security_group_association",
"azurerm_user_assigned_identity",
"azurerm_virtual_network",
"azurerm_windows_function_app",
"azurerm_windows_virtual_machine",
"azurerm_windows_web_app"
],
"total_input_resources": 27,
"provider_resource_count": 27,
"normalized_resource_count": 27,
"unsupported_resource_types": {}
},
"resources": [
{
"address": "azurerm_key_vault.application",
"provider": "azure",
"resource_type": "azurerm_key_vault",
"name": "application",
"category": "data",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.KeyVault/vaults/tfstride-application",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": false,
"data_sensitivity": "sensitive",
"metadata": {
"name": "tfstride-application",
"key_vault_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.KeyVault/vaults/tfstride-application",
"location": "eastus",
"network_default_action": "Allow",
"public_network_fallback_state": "enabled",
"key_vault_network_ip_rules": [],
"key_vault_network_subnet_ids": [],
"key_vault_access_policies": [],
"public_network_access_enabled": true,
"purge_protection_enabled": false,
"rbac_authorization_enabled": false,
"storage_encrypted": true,
"direct_internet_reachable": true,
"internet_ingress_capable": true,
"public_access_reasons": [
"public_network_access_enabled is true",
"effective network default_action is Allow"
],
"internet_ingress_reasons": [
"public_network_access_enabled is true",
"effective network default_action is Allow"
]
}
},
{
"address": "azurerm_kubernetes_cluster.platform",
"provider": "azure",
"resource_type": "azurerm_kubernetes_cluster",
"name": "platform",
"category": "compute",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.ContainerService/managedClusters/tfstride-platform",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-platform",
"location": "eastus",
"aks_cluster_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.ContainerService/managedClusters/tfstride-platform",
"aks_private_cluster_state": "disabled",
"aks_authorized_ip_ranges": [],
"aks_authorized_ip_ranges_state": "not_configured",
"aks_api_server_vnet_integration_state": "unknown",
"aks_local_account_state": "unknown",
"aks_rbac_state": "unknown",
"aks_aad_rbac_state": "not_configured",
"aks_aad_managed_state": "unknown",
"aks_aad_azure_rbac_state": "unknown",
"aks_aad_admin_group_object_ids": [],
"aks_oidc_issuer_state": "unknown",
"aks_workload_identity_state": "unknown",
"aks_network_policy_state": "unknown",
"aks_user_assigned_identity_ids": [],
"aks_kubelet_identity_state": "not_configured",
"aks_kubelet_identities": [],
"aks_kms_state": "not_configured",
"aks_oms_agent_state": "not_configured",
"aks_defender_state": "not_configured",
"aks_azure_policy_state": "unknown",
"aks_maintenance_windows": []
}
},
{
"address": "azurerm_linux_virtual_machine.web",
"provider": "azure",
"resource_type": "azurerm_linux_virtual_machine",
"name": "web",
"category": "compute",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Compute/virtualMachines/tfstride-web",
"arn": null,
"vpc_id": "azurerm_virtual_network.main",
"subnet_ids": [
"azurerm_subnet.web"
],
"security_group_ids": [
"azurerm_network_security_group.web_nic",
"azurerm_network_security_group.web_subnet"
],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-web",
"location": "eastus",
"vm_size": "Standard_B2s",
"os_type": "linux",
"network_interface_references": [
"azurerm_network_interface.web.id"
],
"identity_type": "UserAssigned",
"attached_identity_references": [
"azurerm_user_assigned_identity.deploy.id"
],
"resolved_network_interface_addresses": [
"azurerm_network_interface.web"
],
"resolved_public_ip_addresses": [
"azurerm_public_ip.web"
],
"public_access_reasons": [
"virtual machine is attached to a network interface with a public IP"
],
"public_compute_exposure_paths": [
{
"protocol": "tcp",
"from_port": 22,
"to_port": 22,
"network_interfaces": [
"azurerm_network_interface.web"
],
"public_ip_resources": [
"azurerm_public_ip.web"
],
"public_ips": [
"azurerm_public_ip.web (203.0.113.10)"
],
"network_security_groups": [
"azurerm_network_security_group.web_nic",
"azurerm_network_security_group.web_subnet"
],
"network_security_rules": [
"azurerm_network_security_group.web_nic rule allow-ssh priority 200 allows tcp 22 from Internet",
"azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet"
]
}
],
"internet_ingress_capable": true,
"publicly_accessible": true,
"direct_internet_reachable": true,
"internet_ingress_reasons": [
"azurerm_network_security_group.web_nic rule allow-ssh priority 200 allows tcp 22 from Internet",
"azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet"
],
"public_exposure_reasons": [
"virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress"
]
}
},
{
"address": "azurerm_network_interface.admin",
"provider": "azure",
"resource_type": "azurerm_network_interface",
"name": "admin",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkInterfaces/tfstride-admin",
"arn": null,
"vpc_id": "azurerm_virtual_network.main",
"subnet_ids": [
"azurerm_subnet.web"
],
"security_group_ids": [
"azurerm_network_security_group.admin_nic",
"azurerm_network_security_group.web_subnet"
],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-admin",
"location": "eastus",
"ip_configurations": [
{
"name": "primary",
"subnet_id": "azurerm_subnet.web.id",
"private_ip_address": "10.20.1.20",
"private_ip_address_allocation": "Static",
"public_ip_address_id": "azurerm_public_ip.admin.id"
}
],
"public_ip_references": [
"azurerm_public_ip.admin.id"
],
"ip_forwarding_enabled": false,
"resolved_network_security_group_addresses": [
"azurerm_network_security_group.admin_nic"
],
"resolved_subnet_addresses": [
"azurerm_subnet.web"
],
"resolved_public_ip_addresses": [
"azurerm_public_ip.admin"
],
"public_access_reasons": [
"network interface references a public IP address"
]
}
},
{
"address": "azurerm_network_interface.web",
"provider": "azure",
"resource_type": "azurerm_network_interface",
"name": "web",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkInterfaces/tfstride-web",
"arn": null,
"vpc_id": "azurerm_virtual_network.main",
"subnet_ids": [
"azurerm_subnet.web"
],
"security_group_ids": [
"azurerm_network_security_group.web_nic",
"azurerm_network_security_group.web_subnet"
],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-web",
"location": "eastus",
"ip_configurations": [
{
"name": "primary",
"subnet_id": "azurerm_subnet.web.id",
"private_ip_address": "10.20.1.10",
"private_ip_address_allocation": "Static",
"public_ip_address_id": "azurerm_public_ip.web.id"
}
],
"public_ip_references": [
"azurerm_public_ip.web.id"
],
"ip_forwarding_enabled": false,
"resolved_network_security_group_addresses": [
"azurerm_network_security_group.web_nic"
],
"resolved_subnet_addresses": [
"azurerm_subnet.web"
],
"resolved_public_ip_addresses": [
"azurerm_public_ip.web"
],
"public_access_reasons": [
"network interface references a public IP address"
]
}
},
{
"address": "azurerm_network_interface_security_group_association.admin",
"provider": "azure",
"resource_type": "azurerm_network_interface_security_group_association",
"name": "admin",
"category": "network",
"identifier": "azurerm_network_interface_security_group_association.admin",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"network_interface_reference": "azurerm_network_interface.admin.id",
"network_security_group_reference": "azurerm_network_security_group.admin_nic.id",
"associated_resource_addresses": [
"azurerm_network_interface.admin"
],
"resolved_network_security_group_addresses": [
"azurerm_network_security_group.admin_nic"
]
}
},
{
"address": "azurerm_network_interface_security_group_association.web",
"provider": "azure",
"resource_type": "azurerm_network_interface_security_group_association",
"name": "web",
"category": "network",
"identifier": "azurerm_network_interface_security_group_association.web",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"network_interface_reference": "azurerm_network_interface.web.id",
"network_security_group_reference": "azurerm_network_security_group.web_nic.id",
"associated_resource_addresses": [
"azurerm_network_interface.web"
],
"resolved_network_security_group_addresses": [
"azurerm_network_security_group.web_nic"
]
}
},
{
"address": "azurerm_network_security_group.admin_nic",
"provider": "azure",
"resource_type": "azurerm_network_security_group",
"name": "admin_nic",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/admin-nic",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [
{
"direction": "ingress",
"protocol": "tcp",
"from_port": 3389,
"to_port": 3389,
"cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"ipv6_cidr_blocks": [],
"referenced_security_group_ids": [],
"description": null
}
],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "admin-nic",
"location": "eastus",
"network_security_rules": [
{
"name": "deny-ssh",
"rule_priority": 100,
"rule_direction": "ingress",
"access": "deny",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"22"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
},
{
"name": "allow-rdp",
"rule_priority": 200,
"rule_direction": "ingress",
"access": "allow",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"3389"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
}
],
"standalone_rule_addresses": [
"azurerm_network_security_rule.allow_rdp"
],
"associated_resource_addresses": [
"azurerm_network_interface.admin"
]
}
},
{
"address": "azurerm_network_security_group.web_nic",
"provider": "azure",
"resource_type": "azurerm_network_security_group",
"name": "web_nic",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-nic",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [
{
"direction": "ingress",
"protocol": "tcp",
"from_port": 22,
"to_port": 22,
"cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"ipv6_cidr_blocks": [],
"referenced_security_group_ids": [],
"description": null
}
],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "web-nic",
"location": "eastus",
"network_security_rules": [
{
"name": "deny-rdp",
"rule_priority": 100,
"rule_direction": "ingress",
"access": "deny",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"3389"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
},
{
"name": "allow-ssh",
"rule_priority": 200,
"rule_direction": "ingress",
"access": "allow",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"22"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
}
],
"standalone_rule_addresses": [
"azurerm_network_security_rule.allow_ssh"
],
"associated_resource_addresses": [
"azurerm_network_interface.web"
]
}
},
{
"address": "azurerm_network_security_group.web_subnet",
"provider": "azure",
"resource_type": "azurerm_network_security_group",
"name": "web_subnet",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-subnet",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [
{
"direction": "ingress",
"protocol": "tcp",
"from_port": 0,
"to_port": 65535,
"cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"ipv6_cidr_blocks": [],
"referenced_security_group_ids": [],
"description": null
}
],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "web-subnet",
"location": "eastus",
"network_security_rules": [
{
"name": "allow-internet-tcp",
"rule_priority": 300,
"rule_direction": "ingress",
"access": "allow",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"*"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
}
],
"associated_resource_addresses": [
"azurerm_subnet.web"
]
}
},
{
"address": "azurerm_network_security_rule.allow_rdp",
"provider": "azure",
"resource_type": "azurerm_network_security_rule",
"name": "allow_rdp",
"category": "network",
"identifier": "allow-rdp",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [
{
"direction": "ingress",
"protocol": "tcp",
"from_port": 3389,
"to_port": 3389,
"cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"ipv6_cidr_blocks": [],
"referenced_security_group_ids": [],
"description": null
}
],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "allow-rdp",
"network_security_group_reference": "azurerm_network_security_group.admin_nic.name",
"network_security_rules": [
{
"name": "allow-rdp",
"rule_priority": 200,
"rule_direction": "ingress",
"access": "allow",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"3389"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
}
]
}
},
{
"address": "azurerm_network_security_rule.allow_ssh",
"provider": "azure",
"resource_type": "azurerm_network_security_rule",
"name": "allow_ssh",
"category": "network",
"identifier": "allow-ssh",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [
{
"direction": "ingress",
"protocol": "tcp",
"from_port": 22,
"to_port": 22,
"cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"ipv6_cidr_blocks": [],
"referenced_security_group_ids": [],
"description": null
}
],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "allow-ssh",
"network_security_group_reference": "azurerm_network_security_group.web_nic.name",
"network_security_rules": [
{
"name": "allow-ssh",
"rule_priority": 200,
"rule_direction": "ingress",
"access": "allow",
"protocol": "tcp",
"source_address_prefixes": [
"Internet"
],
"source_cidr_blocks": [
"0.0.0.0/0",
"::/0"
],
"source_port_ranges": [
"*"
],
"destination_address_prefixes": [
"*"
],
"destination_port_ranges": [
"22"
],
"source_application_security_group_ids": [],
"destination_application_security_group_ids": [],
"description": null
}
]
}
},
{
"address": "azurerm_public_ip.admin",
"provider": "azure",
"resource_type": "azurerm_public_ip",
"name": "admin",
"category": "edge",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/publicIPAddresses/tfstride-admin",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-admin",
"location": "eastus",
"public_ip_address": "203.0.113.20",
"associated_resource_addresses": [
"azurerm_network_interface.admin"
]
}
},
{
"address": "azurerm_public_ip.web",
"provider": "azure",
"resource_type": "azurerm_public_ip",
"name": "web",
"category": "edge",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/publicIPAddresses/tfstride-web",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-web",
"location": "eastus",
"public_ip_address": "203.0.113.10",
"associated_resource_addresses": [
"azurerm_network_interface.web"
]
}
},
{
"address": "azurerm_role_assignment.storage_owner",
"provider": "azure",
"resource_type": "azurerm_role_assignment",
"name": "storage_owner",
"category": "iam",
"identifier": "azurerm_role_assignment.storage_owner",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"role_assignment_scope": "azurerm_storage_account.logs.id",
"role_definition_name": "Storage Blob Data Owner",
"principal_id": "11111111-1111-1111-1111-111111111111",
"principal_type": "ServicePrincipal",
"key_vault_role_assignments": [
{
"source": "azurerm_role_assignment.storage_owner",
"scope": "azurerm_storage_account.logs.id",
"role_definition_name": "Storage Blob Data Owner",
"role_definition_id": null,
"principal_id": "11111111-1111-1111-1111-111111111111",
"principal_type": "ServicePrincipal",
"scope_kind": "resource",
"target_resource_address": "azurerm_storage_account.logs",
"target_resource_type": "azurerm_storage_account",
"breadth_signals": [
"broad_builtin_role",
"sensitive_resource_scope"
]
}
],
"key_vault_authorization_uncertainties": [],
"role_assignment_scope_kind": "resource",
"role_assignment_breadth_signals": [
"broad_builtin_role",
"sensitive_resource_scope"
],
"role_assignment_breadth_mitigations": [],
"role_assignment_target_resource_address": "azurerm_storage_account.logs",
"role_assignment_target_resource_type": "azurerm_storage_account",
"privileged_access_grants": [
{
"provider": "azure",
"principal_type": "managed-identity",
"principal_identifier": "11111111-1111-1111-1111-111111111111",
"principal_display_name": "azurerm_user_assigned_identity.deploy",
"principal_source_address": "azurerm_user_assigned_identity.deploy",
"scope_kind": "resource",
"scope_value": "azurerm_storage_account.logs.id",
"scope_source_address": "azurerm_storage_account.logs",
"privilege_categories": [
"data-admin"
],
"confidence": "high",
"assignment_source_address": "azurerm_role_assignment.storage_owner",
"role_name": "Storage Blob Data Owner",
"role_id": null,
"permission_patterns": [
"Storage Blob Data Owner"
],
"evidence": [
"source=azurerm_role_assignment.storage_owner",
"role=Storage Blob Data Owner",
"principal_id=11111111-1111-1111-1111-111111111111",
"principal_type=ServicePrincipal",
"scope=azurerm_storage_account.logs.id",
"scope_kind=resource",
"target_resource=azurerm_storage_account.logs",
"breadth_signal=broad_builtin_role",
"breadth_signal=sensitive_resource_scope"
],
"uncertainties": []
}
],
"resolved_managed_identity_address": "azurerm_user_assigned_identity.deploy"
}
},
{
"address": "azurerm_storage_account.assets",
"provider": "azure",
"resource_type": "azurerm_storage_account",
"name": "assets",
"category": "data",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepublicassets",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "sensitive",
"metadata": {
"name": "tfstridepublicassets",
"storage_account_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepublicassets",
"network_default_action": "Allow",
"allow_nested_items_to_be_public": true,
"shared_access_key_enabled": true,
"storage_infrastructure_encryption_enabled": true,
"storage_customer_managed_key_id": "azurerm_key_vault_key.storage.id",
"storage_customer_managed_key_identity_id": "azurerm_user_assigned_identity.storage.id",
"storage_blob_versioning_enabled": true,
"storage_blob_delete_retention_days": 30,
"storage_container_delete_retention_days": 14,
"storage_blob_restore_policy_days": 7,
"public_network_fallback_state": "enabled",
"public_network_access_enabled": true,
"min_tls_version": "TLS1_1",
"storage_encrypted": true,
"network_rule_source_address": "azurerm_storage_account_network_rules.assets",
"direct_internet_reachable": true,
"internet_ingress_capable": true,
"public_access_reasons": [
"public_network_access_enabled is true",
"effective network default_action is Allow"
],
"internet_ingress_reasons": [
"public_network_access_enabled is true",
"effective network default_action is Allow"
],
"public_container_addresses": [
"azurerm_storage_container.public_assets"
],
"publicly_accessible": true,
"public_exposure_reasons": [
"container_access_type is blob",
"azurerm_storage_account.assets allows nested items to be public",
"azurerm_storage_account.assets is reachable through its public network endpoint"
]
}
},
{
"address": "azurerm_storage_account.logs",
"provider": "azure",
"resource_type": "azurerm_storage_account",
"name": "logs",
"category": "data",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepubliclogs",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "sensitive",
"metadata": {
"name": "tfstridepubliclogs",
"storage_account_id": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepubliclogs",
"network_default_action": "Allow",
"allow_nested_items_to_be_public": true,
"shared_access_key_enabled": true,
"storage_infrastructure_encryption_enabled": true,
"storage_customer_managed_key_id": "azurerm_key_vault_key.storage.id",
"storage_customer_managed_key_identity_id": "azurerm_user_assigned_identity.storage.id",
"storage_blob_versioning_enabled": true,
"storage_blob_delete_retention_days": 30,
"storage_container_delete_retention_days": 14,
"storage_blob_restore_policy_days": 7,
"public_network_fallback_state": "enabled",
"public_network_access_enabled": true,
"min_tls_version": "TLS1_0",
"storage_encrypted": true,
"network_rule_source_address": "azurerm_storage_account_network_rules.logs",
"direct_internet_reachable": true,
"internet_ingress_capable": true,
"public_access_reasons": [
"public_network_access_enabled is true",
"effective network default_action is Allow"
],
"internet_ingress_reasons": [
"public_network_access_enabled is true",
"effective network default_action is Allow"
],
"public_container_addresses": [
"azurerm_storage_container.public_logs",
"azurerm_storage_container.public_backups"
],
"publicly_accessible": true,
"public_exposure_reasons": [
"container_access_type is blob",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
]
}
},
{
"address": "azurerm_storage_account_network_rules.assets",
"provider": "azure",
"resource_type": "azurerm_storage_account_network_rules",
"name": "assets",
"category": "network",
"identifier": "azurerm_storage_account.assets.id",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"storage_account_reference": "azurerm_storage_account.assets.id",
"network_rule_source_address": "azurerm_storage_account_network_rules.assets",
"network_default_action": "Allow",
"resolved_storage_account_address": "azurerm_storage_account.assets"
}
},
{
"address": "azurerm_storage_account_network_rules.logs",
"provider": "azure",
"resource_type": "azurerm_storage_account_network_rules",
"name": "logs",
"category": "network",
"identifier": "azurerm_storage_account.logs.id",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"storage_account_reference": "azurerm_storage_account.logs.id",
"network_rule_source_address": "azurerm_storage_account_network_rules.logs",
"network_default_action": "Allow",
"resolved_storage_account_address": "azurerm_storage_account.logs"
}
},
{
"address": "azurerm_storage_container.public_assets",
"provider": "azure",
"resource_type": "azurerm_storage_container",
"name": "public_assets",
"category": "data",
"identifier": "public-assets",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "sensitive",
"metadata": {
"name": "public-assets",
"storage_account_reference": "azurerm_storage_account.assets.id",
"container_access_type": "blob",
"storage_encrypted": true,
"resolved_storage_account_address": "azurerm_storage_account.assets",
"publicly_accessible": true,
"direct_internet_reachable": true,
"public_access_reasons": [
"container_access_type is blob",
"azurerm_storage_account.assets allows nested items to be public",
"azurerm_storage_account.assets is reachable through its public network endpoint"
],
"public_exposure_reasons": [
"container_access_type is blob",
"azurerm_storage_account.assets allows nested items to be public",
"azurerm_storage_account.assets is reachable through its public network endpoint"
]
}
},
{
"address": "azurerm_storage_container.public_backups",
"provider": "azure",
"resource_type": "azurerm_storage_container",
"name": "public_backups",
"category": "data",
"identifier": "public-backups",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "sensitive",
"metadata": {
"name": "public-backups",
"storage_account_reference": "azurerm_storage_account.logs.id",
"container_access_type": "blob",
"storage_encrypted": true,
"resolved_storage_account_address": "azurerm_storage_account.logs",
"publicly_accessible": true,
"direct_internet_reachable": true,
"public_access_reasons": [
"container_access_type is blob",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
],
"public_exposure_reasons": [
"container_access_type is blob",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
]
}
},
{
"address": "azurerm_storage_container.public_logs",
"provider": "azure",
"resource_type": "azurerm_storage_container",
"name": "public_logs",
"category": "data",
"identifier": "public-logs",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "sensitive",
"metadata": {
"name": "public-logs",
"storage_account_reference": "azurerm_storage_account.logs.id",
"container_access_type": "container",
"storage_encrypted": true,
"resolved_storage_account_address": "azurerm_storage_account.logs",
"publicly_accessible": true,
"direct_internet_reachable": true,
"public_access_reasons": [
"container_access_type is container",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
],
"public_exposure_reasons": [
"container_access_type is container",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
]
}
},
{
"address": "azurerm_subnet.web",
"provider": "azure",
"resource_type": "azurerm_subnet",
"name": "web",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/virtualNetworks/tfstride-main/subnets/web",
"arn": null,
"vpc_id": "azurerm_virtual_network.main",
"subnet_ids": [],
"security_group_ids": [
"azurerm_network_security_group.web_subnet"
],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "web",
"virtual_network_reference": "azurerm_virtual_network.main.name",
"address_prefixes": [
"10.20.1.0/24"
],
"default_outbound_access_enabled": false,
"resolved_virtual_network_address": "azurerm_virtual_network.main",
"resolved_network_security_group_addresses": [
"azurerm_network_security_group.web_subnet"
]
}
},
{
"address": "azurerm_subnet_network_security_group_association.web",
"provider": "azure",
"resource_type": "azurerm_subnet_network_security_group_association",
"name": "web",
"category": "network",
"identifier": "azurerm_subnet_network_security_group_association.web",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"subnet_reference": "azurerm_subnet.web.id",
"network_security_group_reference": "azurerm_network_security_group.web_subnet.id",
"associated_resource_addresses": [
"azurerm_subnet.web"
],
"resolved_network_security_group_addresses": [
"azurerm_network_security_group.web_subnet"
]
}
},
{
"address": "azurerm_user_assigned_identity.deploy",
"provider": "azure",
"resource_type": "azurerm_user_assigned_identity",
"name": "deploy",
"category": "iam",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.ManagedIdentity/userAssignedIdentities/tfstride-deploy",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-deploy",
"location": "eastus",
"identity_type": "UserAssigned",
"principal_id": "11111111-1111-1111-1111-111111111111",
"client_id": "22222222-2222-2222-2222-222222222222",
"tenant_id": "00000000-0000-0000-0000-000000000001",
"managed_identity_role_assignments": [
{
"source": "azurerm_role_assignment.storage_owner",
"scope": "azurerm_storage_account.logs.id",
"role_definition_name": "Storage Blob Data Owner",
"role_definition_id": null,
"principal_id": "11111111-1111-1111-1111-111111111111",
"principal_type": "ServicePrincipal",
"scope_kind": "resource",
"target_resource_address": "azurerm_storage_account.logs",
"target_resource_type": "azurerm_storage_account",
"breadth_signals": [
"broad_builtin_role",
"sensitive_resource_scope"
]
}
],
"privileged_access_grants": [
{
"provider": "azure",
"principal_type": "managed-identity",
"principal_identifier": "11111111-1111-1111-1111-111111111111",
"principal_display_name": "azurerm_user_assigned_identity.deploy",
"principal_source_address": "azurerm_user_assigned_identity.deploy",
"scope_kind": "resource",
"scope_value": "azurerm_storage_account.logs.id",
"scope_source_address": "azurerm_storage_account.logs",
"privilege_categories": [
"data-admin"
],
"confidence": "high",
"assignment_source_address": "azurerm_role_assignment.storage_owner",
"role_name": "Storage Blob Data Owner",
"role_id": null,
"permission_patterns": [
"Storage Blob Data Owner"
],
"evidence": [
"source=azurerm_role_assignment.storage_owner",
"role=Storage Blob Data Owner",
"principal_id=11111111-1111-1111-1111-111111111111",
"principal_type=ServicePrincipal",
"scope=azurerm_storage_account.logs.id",
"scope_kind=resource",
"target_resource=azurerm_storage_account.logs",
"breadth_signal=broad_builtin_role",
"breadth_signal=sensitive_resource_scope"
],
"uncertainties": []
}
]
}
},
{
"address": "azurerm_virtual_network.main",
"provider": "azure",
"resource_type": "azurerm_virtual_network",
"name": "main",
"category": "network",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/virtualNetworks/tfstride-main",
"arn": null,
"vpc_id": null,
"subnet_ids": [],
"security_group_ids": [],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": false,
"public_exposure": false,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-main",
"location": "eastus",
"address_space": [
"10.20.0.0/16"
]
}
},
{
"address": "azurerm_windows_virtual_machine.admin",
"provider": "azure",
"resource_type": "azurerm_windows_virtual_machine",
"name": "admin",
"category": "compute",
"identifier": "/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Compute/virtualMachines/tfstride-admin",
"arn": null,
"vpc_id": "azurerm_virtual_network.main",
"subnet_ids": [
"azurerm_subnet.web"
],
"security_group_ids": [
"azurerm_network_security_group.admin_nic",
"azurerm_network_security_group.web_subnet"
],
"attached_role_arns": [],
"network_rules": [],
"policy_statements": [],
"public_access_configured": true,
"public_exposure": true,
"data_sensitivity": "standard",
"metadata": {
"name": "tfstride-admin",
"location": "eastus",
"vm_size": "Standard_B2s",
"os_type": "windows",
"network_interface_references": [
"azurerm_network_interface.admin.id"
],
"resolved_network_interface_addresses": [
"azurerm_network_interface.admin"
],
"resolved_public_ip_addresses": [
"azurerm_public_ip.admin"
],
"public_access_reasons": [
"virtual machine is attached to a network interface with a public IP"
],
"public_compute_exposure_paths": [
{
"protocol": "tcp",
"from_port": 3389,
"to_port": 3389,
"network_interfaces": [
"azurerm_network_interface.admin"
],
"public_ip_resources": [
"azurerm_public_ip.admin"
],
"public_ips": [
"azurerm_public_ip.admin (203.0.113.20)"
],
"network_security_groups": [
"azurerm_network_security_group.admin_nic",
"azurerm_network_security_group.web_subnet"
],
"network_security_rules": [
"azurerm_network_security_group.admin_nic rule allow-rdp priority 200 allows tcp 3389 from Internet",
"azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet"
]
}
],
"internet_ingress_capable": true,
"publicly_accessible": true,
"direct_internet_reachable": true,
"internet_ingress_reasons": [
"azurerm_network_security_group.admin_nic rule allow-rdp priority 200 allows tcp 3389 from Internet",
"azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet"
],
"public_exposure_reasons": [
"virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress"
]
}
}
]
},
"trust_boundaries": [
{
"identifier": "internet-to-service:internet->azurerm_key_vault.application",
"boundary_type": "internet-to-service",
"source": "internet",
"target": "azurerm_key_vault.application",
"description": "Traffic can cross from the public internet to azurerm_key_vault.application.",
"rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
},
{
"identifier": "internet-to-service:internet->azurerm_linux_virtual_machine.web",
"boundary_type": "internet-to-service",
"source": "internet",
"target": "azurerm_linux_virtual_machine.web",
"description": "Traffic can cross from the public internet to azurerm_linux_virtual_machine.web.",
"rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
},
{
"identifier": "internet-to-service:internet->azurerm_storage_account.assets",
"boundary_type": "internet-to-service",
"source": "internet",
"target": "azurerm_storage_account.assets",
"description": "Traffic can cross from the public internet to azurerm_storage_account.assets.",
"rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
},
{
"identifier": "internet-to-service:internet->azurerm_storage_account.logs",
"boundary_type": "internet-to-service",
"source": "internet",
"target": "azurerm_storage_account.logs",
"description": "Traffic can cross from the public internet to azurerm_storage_account.logs.",
"rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
},
{
"identifier": "internet-to-service:internet->azurerm_windows_virtual_machine.admin",
"boundary_type": "internet-to-service",
"source": "internet",
"target": "azurerm_windows_virtual_machine.admin",
"description": "Traffic can cross from the public internet to azurerm_windows_virtual_machine.admin.",
"rationale": "The resource is directly reachable or intentionally exposed to unauthenticated network clients."
}
],
"findings": [
{
"fingerprint": "sha256:ee4720085ef92d401a724f311fa3b96c667c0049f526cae7cf6b5a82d70aaab7",
"title": "AKS control plane is public without narrow authorized IP ranges",
"rule_id": "azure-aks-api-server-public-unrestricted",
"category": "Elevation of Privilege",
"severity": "high",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform has AKS private cluster mode disabled and does not define narrow authorized IP ranges for the Kubernetes API server. The control plane is publicly reachable without a reviewed source range restriction.",
"recommended_mitigation": "Enable private cluster mode where possible, or configure `api_server_access_profile.authorized_ip_ranges` with narrow trusted CIDRs and avoid internet-wide source ranges.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "control_plane_posture",
"values": [
"private_cluster_state=disabled",
"authorized_ip_ranges_state=not_configured",
"api_server_vnet_integration_state=unknown"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 1,
"data_sensitivity": 0,
"lateral_movement": 1,
"blast_radius": 2,
"final_score": 6,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:38ff20b84ecb7ec38889185c288ca2e4e4aafb85fcef59af77181dc441bb1030",
"title": "Azure Storage account permits Shared Key authorization",
"rule_id": "azure-storage-account-shared-key-enabled",
"category": "Elevation of Privilege",
"severity": "high",
"affected_resources": [
"azurerm_storage_account.assets"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.assets permits Shared Key authorization. Account keys provide broad data-plane authority and are harder to constrain and attribute than Microsoft Entra ID identities.",
"recommended_mitigation": "Disable Shared Key authorization where supported, use Microsoft Entra ID and managed identities, and configure the AzureRM provider to use Azure AD for storage operations.",
"evidence": [
{
"key": "authorization_posture",
"values": [
"shared_access_key_enabled is true"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 2,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 7,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:2860dcfd5ee2eb18196ecd147fbf7fee28feb164b7814db5b3a8e8aca2ef0b21",
"title": "Azure Storage account permits Shared Key authorization",
"rule_id": "azure-storage-account-shared-key-enabled",
"category": "Elevation of Privilege",
"severity": "high",
"affected_resources": [
"azurerm_storage_account.logs"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.logs permits Shared Key authorization. Account keys provide broad data-plane authority and are harder to constrain and attribute than Microsoft Entra ID identities.",
"recommended_mitigation": "Disable Shared Key authorization where supported, use Microsoft Entra ID and managed identities, and configure the AzureRM provider to use Azure AD for storage operations.",
"evidence": [
{
"key": "authorization_posture",
"values": [
"shared_access_key_enabled is true"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 2,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 7,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:f8512afe7c260af46cdaa7109b886f034ebb082a479abcb96b9aea005af65c53",
"title": "Azure Storage account permits nested public blob access",
"rule_id": "azure-storage-account-nested-public-access-enabled",
"category": "Information Disclosure",
"severity": "high",
"affected_resources": [
"azurerm_storage_account.assets"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.assets permits containers and blobs to opt into anonymous public access. This account-level setting allows a subordinate container configuration to expose stored data.",
"recommended_mitigation": "Set `allow_nested_items_to_be_public` to `false` so containers and blobs cannot opt into anonymous public access.",
"evidence": [
{
"key": "public_access_posture",
"values": [
"allow_nested_items_to_be_public is true"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 1,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 6,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:3381ec17c4beeeb18ff76272dc5737835861ce4177eb47aff235e331fbd931f2",
"title": "Azure Storage account permits nested public blob access",
"rule_id": "azure-storage-account-nested-public-access-enabled",
"category": "Information Disclosure",
"severity": "high",
"affected_resources": [
"azurerm_storage_account.logs"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.logs permits containers and blobs to opt into anonymous public access. This account-level setting allows a subordinate container configuration to expose stored data.",
"recommended_mitigation": "Set `allow_nested_items_to_be_public` to `false` so containers and blobs cannot opt into anonymous public access.",
"evidence": [
{
"key": "public_access_posture",
"values": [
"allow_nested_items_to_be_public is true"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 1,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 6,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:d4cf28797223601c6f7af1e4c07c9114c873fb3ec055bde5aa37ceeb42312014",
"title": "Azure managed identity has broad RBAC authority",
"rule_id": "azure-managed-identity-broad-rbac",
"category": "Elevation of Privilege",
"severity": "high",
"affected_resources": [
"azurerm_user_assigned_identity.deploy",
"azurerm_role_assignment.storage_owner",
"azurerm_storage_account.logs"
],
"trust_boundary_id": null,
"rationale": "azurerm_user_assigned_identity.deploy has Azure role assignments with broad scope or high-impact built-in roles. These grants expand what the managed identity can do if the workload or deployment path using it is compromised.",
"recommended_mitigation": "Replace broad managed identity role assignments with least-privilege resource-scoped roles, split deployment and runtime identities, and avoid subscription or resource-group scope unless required.",
"evidence": [
{
"key": "managed_identity",
"values": [
"address=azurerm_user_assigned_identity.deploy",
"identity_type=UserAssigned",
"principal_id=11111111-1111-1111-1111-111111111111",
"client_id=22222222-2222-2222-2222-222222222222"
]
},
{
"key": "role_assignments",
"values": [
"source=azurerm_role_assignment.storage_owner; role=Storage Blob Data Owner; scope=azurerm_storage_account.logs.id; scope_kind=resource; target=azurerm_storage_account.logs; signals=broad_builtin_role,sensitive_resource_scope"
]
},
{
"key": "breadth_signals",
"values": [
"broad_builtin_role",
"sensitive_resource_scope"
]
},
{
"key": "privileged_access",
"values": [
"grant_1=role=Storage Blob Data Owner; categories=data-admin; scope_kind=resource; confidence=high"
]
},
{
"key": "privilege_categories",
"values": [
"data-admin"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 3,
"data_sensitivity": 2,
"lateral_movement": 1,
"blast_radius": 1,
"final_score": 7,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:6860fbff3390072d546c08fdc39f5f04890dd397b6b50f5778eb07b3bc69435f",
"title": "Internet-exposed Azure workload can access sensitive resources",
"rule_id": "azure-public-workload-sensitive-resource-access",
"category": "Information Disclosure",
"severity": "high",
"affected_resources": [
"azurerm_linux_virtual_machine.web",
"azurerm_user_assigned_identity.deploy",
"azurerm_role_assignment.storage_owner",
"azurerm_storage_account.logs"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_linux_virtual_machine.web",
"rationale": "azurerm_user_assigned_identity.deploy is usable by an internet-exposed Azure workload and has a deterministic role assignment to a sensitive Azure resource. This creates a clear public workload to sensitive resource path if the workload identity is abused.",
"recommended_mitigation": "Remove direct internet exposure from the workload, restrict NSG ingress to trusted paths, and narrow the managed identity role assignment to the minimum sensitive resource operations required.",
"evidence": [
{
"key": "public_workloads",
"values": [
"address=azurerm_linux_virtual_machine.web; public_exposure=true; public_exposure_reasons=virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress"
]
},
{
"key": "managed_identity",
"values": [
"address=azurerm_user_assigned_identity.deploy",
"identity_type=UserAssigned",
"principal_id=11111111-1111-1111-1111-111111111111",
"client_id=22222222-2222-2222-2222-222222222222"
]
},
{
"key": "sensitive_resource_assignments",
"values": [
"source=azurerm_role_assignment.storage_owner; role=Storage Blob Data Owner; scope=azurerm_storage_account.logs.id; scope_kind=resource; target=azurerm_storage_account.logs; signals=broad_builtin_role,sensitive_resource_scope"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 3,
"data_sensitivity": 2,
"lateral_movement": 1,
"blast_radius": 2,
"final_score": 10,
"severity": "high",
"computed_severity": null
}
},
{
"fingerprint": "sha256:6fbbef6b6e43667e4015b79b6b63134f351a17b15708169cb96b3e3a5cf1cb66",
"title": "AKS Defender coverage is not enabled",
"rule_id": "azure-aks-defender-not-enabled",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not show deterministic Microsoft Defender for Containers coverage. Missing Defender signals can reduce runtime threat detection and security recommendations for AKS workloads.",
"recommended_mitigation": "Enable Microsoft Defender for Containers for AKS clusters that need runtime threat detection, vulnerability recommendations, and security posture monitoring.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "defender_posture",
"values": [
"defender_state=not_configured"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 2,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:3fb3d8a912ab7b0d3f5417880c7d6aad4d0b28db8b7c0a61495e4a13e1b9e8c3",
"title": "AKS Key Management Service is not configured",
"rule_id": "azure-aks-key-management-service-not-configured",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not show deterministic AKS Key Management Service configuration with a Key Vault key. Kubernetes secrets may not have customer-controlled encryption key ownership represented in the Terraform plan.",
"recommended_mitigation": "Configure AKS Key Management Service with a customer-managed Key Vault key for Kubernetes secrets where customer key ownership or stronger secrets encryption posture is required.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "secret_encryption_posture",
"values": [
"key_management_service_state=not_configured",
"key_vault_key_id is not represented in planned values"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:77478e54d90f05ca7b4a5ac023962a75ccb8d07dc324c5804f4ed68f2fe4331f",
"title": "AKS monitoring agent is not enabled",
"rule_id": "azure-aks-monitoring-agent-not-enabled",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not show deterministic AKS monitoring through the OMS agent and Log Analytics. Missing cluster telemetry can limit detection and investigation of control-plane and workload activity.",
"recommended_mitigation": "Enable the OMS agent or the current Azure Monitor integration for AKS and route cluster telemetry to a retained Log Analytics workspace or centralized logging pipeline.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "monitoring_posture",
"values": [
"oms_agent_state=not_configured",
"log_analytics_workspace_id is not represented in planned values"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 2,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:e948b5da2b4e7cd8461f5af0540aebe16862ddb371889db2d4602af19df45198",
"title": "Azure Key Vault allows unrestricted public network access",
"rule_id": "azure-key-vault-public-network-access",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_key_vault.application"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_key_vault.application",
"rationale": "azurerm_key_vault.application enables its public endpoint with an effective `Allow` network ACL default action. Network reachability does not itself grant data access, but it exposes the sensitive service endpoint to internet clients.",
"recommended_mitigation": "Disable public network access where possible, or configure Key Vault network ACLs with a default action of `Deny` and use reviewed subnets, IP ranges, or private endpoints.",
"evidence": [
{
"key": "network_exposure",
"values": [
"public_network_access_enabled is true",
"effective network_acls.default_action is Allow",
"network exposure is evaluated separately from identity authorization"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:e3662ad9e0def6050cd01b24c1d27a5eff16cf607cf53c8c6f4671d4aed8e5d5",
"title": "Azure Key Vault lacks resolved private endpoint coverage",
"rule_id": "azure-key-vault-missing-private-endpoint",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_key_vault.application"
],
"trust_boundary_id": null,
"rationale": "azurerm_key_vault.application does not have a resolved private endpoint and may allow public Key Vault data-plane access depending on firewall settings. This finding does not claim secret exposure; identity authorization is evaluated separately.",
"recommended_mitigation": "Add a Private Endpoint for the vault, verify data-plane clients use the private path, and explicitly disable public network access where possible.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_key_vault.application",
"type=azurerm_key_vault"
]
},
{
"key": "public_network_fallback",
"values": [
"public_network_fallback_state=enabled",
"public_network_access_enabled is true"
]
},
{
"key": "private_endpoint_coverage",
"values": [
"no resolved private endpoint targets this resource"
]
},
{
"key": "network_acl_posture",
"values": [
"effective default_action is Allow"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:a4da197f205506e47eb8714790441774c83f75ebe9ef638af30bb0b62eee662b",
"title": "Azure Key Vault purge protection is disabled",
"rule_id": "azure-key-vault-purge-protection-disabled",
"category": "Tampering",
"severity": "medium",
"affected_resources": [
"azurerm_key_vault.application"
],
"trust_boundary_id": null,
"rationale": "azurerm_key_vault.application does not enable purge protection. A principal with sufficient deletion authority could permanently remove vault contents during the retention window.",
"recommended_mitigation": "Enable purge protection and retain soft-deleted vault objects long enough to recover from accidental or malicious deletion.",
"evidence": [
{
"key": "recovery_posture",
"values": [
"purge_protection_enabled is false"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:6ab496f60a73a0c7506e9e645fc45a4988a899730493544c752c197305696ede",
"title": "Azure Network Security Group lacks flow-log coverage",
"rule_id": "azure-nsg-flow-logs-not-configured",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_network_security_group.web_subnet"
],
"trust_boundary_id": null,
"rationale": "azurerm_network_security_group.web_subnet does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.",
"recommended_mitigation": "Configure an `azurerm_network_watcher_flow_log` for the NSG, route logs to durable storage, and keep retention long enough for incident response and network investigation workflows.",
"evidence": [
{
"key": "target_network_security_group",
"values": [
"address=azurerm_network_security_group.web_subnet",
"resource_type=azurerm_network_security_group",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-subnet",
"name=web-subnet"
]
},
{
"key": "flow_log_coverage",
"values": [
"target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/web-subnet",
"target_nsg_identifier=azurerm_network_security_group.web_subnet",
"target_nsg_identifier=azurerm_network_security_group.web_subnet.id",
"target_nsg_identifier=web-subnet",
"resolved_nsg_flow_log_count=0",
"azurerm_network_watcher_flow_log resources are not modeled"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 2,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:c447b0503ac4d8870a05aa0d8f1d0725bcf43e8a20c61a7cad0577a49353d7c2",
"title": "Azure Network Security Group lacks flow-log coverage",
"rule_id": "azure-nsg-flow-logs-not-configured",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_network_security_group.web_nic"
],
"trust_boundary_id": null,
"rationale": "azurerm_network_security_group.web_nic does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.",
"recommended_mitigation": "Configure an `azurerm_network_watcher_flow_log` for the NSG, route logs to durable storage, and keep retention long enough for incident response and network investigation workflows.",
"evidence": [
{
"key": "target_network_security_group",
"values": [
"address=azurerm_network_security_group.web_nic",
"resource_type=azurerm_network_security_group",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-nic",
"name=web-nic"
]
},
{
"key": "flow_log_coverage",
"values": [
"target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/web-nic",
"target_nsg_identifier=azurerm_network_security_group.web_nic",
"target_nsg_identifier=azurerm_network_security_group.web_nic.id",
"target_nsg_identifier=web-nic",
"resolved_nsg_flow_log_count=0",
"azurerm_network_watcher_flow_log resources are not modeled"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 2,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:c72e6ddcf6e4793f8817bf214ca2104b60744691d9850e5b39a496f08689cdb6",
"title": "Azure Network Security Group lacks flow-log coverage",
"rule_id": "azure-nsg-flow-logs-not-configured",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_network_security_group.admin_nic"
],
"trust_boundary_id": null,
"rationale": "azurerm_network_security_group.admin_nic does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.",
"recommended_mitigation": "Configure an `azurerm_network_watcher_flow_log` for the NSG, route logs to durable storage, and keep retention long enough for incident response and network investigation workflows.",
"evidence": [
{
"key": "target_network_security_group",
"values": [
"address=azurerm_network_security_group.admin_nic",
"resource_type=azurerm_network_security_group",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/admin-nic",
"name=admin-nic"
]
},
{
"key": "flow_log_coverage",
"values": [
"target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/admin-nic",
"target_nsg_identifier=admin-nic",
"target_nsg_identifier=azurerm_network_security_group.admin_nic",
"target_nsg_identifier=azurerm_network_security_group.admin_nic.id",
"resolved_nsg_flow_log_count=0",
"azurerm_network_watcher_flow_log resources are not modeled"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 2,
"blast_radius": 1,
"final_score": 3,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:5364af5982121950ea863a12942d2f288e55d46485f339c79d6fe45149c013a5",
"title": "Azure Storage account allows TLS below 1.2",
"rule_id": "azure-storage-account-minimum-tls-below-1-2",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.assets"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.assets accepts `TLS1_1` as its minimum protocol version. Deprecated TLS versions weaken transport protection for storage data-plane requests.",
"recommended_mitigation": "Set `min_tls_version` to `TLS1_2` and remove clients that require deprecated TLS versions.",
"evidence": [
{
"key": "transport_posture",
"values": [
"min_tls_version is TLS1_1"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:b34d30cc90a35bd61e1ecb61b71478b6b50242273f2645cca925dc0bbbdda849",
"title": "Azure Storage account allows TLS below 1.2",
"rule_id": "azure-storage-account-minimum-tls-below-1-2",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.logs"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.logs accepts `TLS1_0` as its minimum protocol version. Deprecated TLS versions weaken transport protection for storage data-plane requests.",
"recommended_mitigation": "Set `min_tls_version` to `TLS1_2` and remove clients that require deprecated TLS versions.",
"evidence": [
{
"key": "transport_posture",
"values": [
"min_tls_version is TLS1_0"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:9386189375f80a7cd2576d28213d6162e220662df2e16817b0e7cf97244b1175",
"title": "Azure Storage account allows unrestricted public network access",
"rule_id": "azure-storage-account-public-network-unrestricted",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.assets"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_storage_account.assets",
"rationale": "azurerm_storage_account.assets enables its public network endpoint with an effective `Allow` default action. Storage data-plane endpoints are reachable without a default-deny network boundary.",
"recommended_mitigation": "Disable public network access where possible, or set the effective storage network default action to `Deny` and allow only reviewed subnets, IP ranges, or private endpoints.",
"evidence": [
{
"key": "network_posture",
"values": [
"public_network_access_enabled is true",
"effective default_action is Allow",
"network rule source is azurerm_storage_account_network_rules.assets"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:c6d248589d63ac56ab7b5f2ac0dd0a6584cf8e622f60aa55f68f377cab47d007",
"title": "Azure Storage account allows unrestricted public network access",
"rule_id": "azure-storage-account-public-network-unrestricted",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.logs"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_storage_account.logs",
"rationale": "azurerm_storage_account.logs enables its public network endpoint with an effective `Allow` default action. Storage data-plane endpoints are reachable without a default-deny network boundary.",
"recommended_mitigation": "Disable public network access where possible, or set the effective storage network default action to `Deny` and allow only reviewed subnets, IP ranges, or private endpoints.",
"evidence": [
{
"key": "network_posture",
"values": [
"public_network_access_enabled is true",
"effective default_action is Allow",
"network rule source is azurerm_storage_account_network_rules.logs"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:cc94468815c3958879d703f07c80cee7ee2a4ece0011f82b8b52b448fd0bfdf4",
"title": "Azure Storage account lacks resolved private endpoint coverage",
"rule_id": "azure-storage-account-missing-private-endpoint",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.assets"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.assets does not have a resolved private endpoint and may remain reachable through public Azure Storage data-plane endpoints. Network rules can reduce exposure, but they are not equivalent to private-endpoint-only access unless public network fallback is disabled.",
"recommended_mitigation": "Add a Private Endpoint for the required storage subresources, verify clients use private paths, and explicitly disable public network access where possible.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_storage_account.assets",
"type=azurerm_storage_account"
]
},
{
"key": "public_network_fallback",
"values": [
"public_network_fallback_state=enabled",
"public_network_access_enabled is true"
]
},
{
"key": "private_endpoint_coverage",
"values": [
"no resolved private endpoint targets this resource"
]
},
{
"key": "network_acl_posture",
"values": [
"effective default_action is Allow",
"network rule source is azurerm_storage_account_network_rules.assets"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:60941091d46d25d52db995fb44545db282f0f4541b9bd11cd966da5b4ccceacb",
"title": "Azure Storage account lacks resolved private endpoint coverage",
"rule_id": "azure-storage-account-missing-private-endpoint",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.logs"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.logs does not have a resolved private endpoint and may remain reachable through public Azure Storage data-plane endpoints. Network rules can reduce exposure, but they are not equivalent to private-endpoint-only access unless public network fallback is disabled.",
"recommended_mitigation": "Add a Private Endpoint for the required storage subresources, verify clients use private paths, and explicitly disable public network access where possible.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_storage_account.logs",
"type=azurerm_storage_account"
]
},
{
"key": "public_network_fallback",
"values": [
"public_network_fallback_state=enabled",
"public_network_access_enabled is true"
]
},
{
"key": "private_endpoint_coverage",
"values": [
"no resolved private endpoint targets this resource"
]
},
{
"key": "network_acl_posture",
"values": [
"effective default_action is Allow",
"network rule source is azurerm_storage_account_network_rules.logs"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:a5ea8f2ff975bdf58d293ce387f4578b2c5dcafef2eb26a77c9f1091ea95ecce",
"title": "Azure Storage container is publicly accessible",
"rule_id": "azure-storage-container-public-access",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.assets",
"azurerm_storage_container.public_assets"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_storage_account.assets",
"rationale": "azurerm_storage_container.public_assets permits anonymous `blob` access through a storage account that allows nested public access and unrestricted public network reachability.",
"recommended_mitigation": "Set the container access type to `private`, disable nested public access on the storage account, and use scoped identities or time-limited access mechanisms for intentional object sharing.",
"evidence": [
{
"key": "public_exposure_reasons",
"values": [
"container_access_type is blob",
"azurerm_storage_account.assets allows nested items to be public",
"azurerm_storage_account.assets is reachable through its public network endpoint"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:f47610bae99564e2f96810bb2f0bd59c26bc694a06ca407730a77faa7298b4ca",
"title": "Azure Storage container is publicly accessible",
"rule_id": "azure-storage-container-public-access",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.logs",
"azurerm_storage_container.public_logs"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_storage_account.logs",
"rationale": "azurerm_storage_container.public_logs permits anonymous `container` access through a storage account that allows nested public access and unrestricted public network reachability.",
"recommended_mitigation": "Set the container access type to `private`, disable nested public access on the storage account, and use scoped identities or time-limited access mechanisms for intentional object sharing.",
"evidence": [
{
"key": "public_exposure_reasons",
"values": [
"container_access_type is container",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:62ecf746893bcac2f1a5cc3a90d16f7a330e679fbe07f63d4d14493fa703d565",
"title": "Azure Storage container is publicly accessible",
"rule_id": "azure-storage-container-public-access",
"category": "Information Disclosure",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.logs",
"azurerm_storage_container.public_backups"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_storage_account.logs",
"rationale": "azurerm_storage_container.public_backups permits anonymous `blob` access through a storage account that allows nested public access and unrestricted public network reachability.",
"recommended_mitigation": "Set the container access type to `private`, disable nested public access on the storage account, and use scoped identities or time-limited access mechanisms for intentional object sharing.",
"evidence": [
{
"key": "public_exposure_reasons",
"values": [
"container_access_type is blob",
"azurerm_storage_account.logs allows nested items to be public",
"azurerm_storage_account.logs is reachable through its public network endpoint"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:07111d0129658172fd2bfbdf975c7e4efed1fd569c653f22546347fa66e71d05",
"title": "Azure resource lacks diagnostic settings",
"rule_id": "azure-diagnostic-settings-missing",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.assets"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.assets has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.",
"recommended_mitigation": "Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_storage_account.assets",
"type=azurerm_storage_account",
"name=tfstridepublicassets",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepublicassets"
]
},
{
"key": "diagnostic_coverage",
"values": [
"no resolved azurerm_monitor_diagnostic_setting targets this resource"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:35d86ccd65fb08a7697e60c0390da781e871a9e2b085c2acecd55b8c2f186019",
"title": "Azure resource lacks diagnostic settings",
"rule_id": "azure-diagnostic-settings-missing",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_storage_account.logs"
],
"trust_boundary_id": null,
"rationale": "azurerm_storage_account.logs has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.",
"recommended_mitigation": "Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_storage_account.logs",
"type=azurerm_storage_account",
"name=tfstridepubliclogs",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepubliclogs"
]
},
{
"key": "diagnostic_coverage",
"values": [
"no resolved azurerm_monitor_diagnostic_setting targets this resource"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:e865a488002e8d0525e5160811c53f01f7aaf91c8dfdc33071d00567f8f5b872",
"title": "Azure resource lacks diagnostic settings",
"rule_id": "azure-diagnostic-settings-missing",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.",
"recommended_mitigation": "Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster",
"name=tfstride-platform",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.ContainerService/managedClusters/tfstride-platform"
]
},
{
"key": "diagnostic_coverage",
"values": [
"no resolved azurerm_monitor_diagnostic_setting targets this resource"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 1,
"lateral_movement": 1,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:6b6ab7b899a0b628803c70ec7669b115f9c2fbd82c847d5ea875f6b5832edf9e",
"title": "Azure resource lacks diagnostic settings",
"rule_id": "azure-diagnostic-settings-missing",
"category": "Repudiation",
"severity": "medium",
"affected_resources": [
"azurerm_key_vault.application"
],
"trust_boundary_id": null,
"rationale": "azurerm_key_vault.application has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.",
"recommended_mitigation": "Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_key_vault.application",
"type=azurerm_key_vault",
"name=tfstride-application",
"identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.KeyVault/vaults/tfstride-application"
]
},
{
"key": "diagnostic_coverage",
"values": [
"no resolved azurerm_monitor_diagnostic_setting targets this resource"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 2,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 5,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:2040c6407379ff7a6112f3f115e614c30949e9a913b4927b185f5aef2da7cbad",
"title": "Internet-exposed Azure virtual machine permits broad ingress",
"rule_id": "azure-public-compute-broad-ingress",
"category": "Spoofing",
"severity": "medium",
"affected_resources": [
"azurerm_linux_virtual_machine.web",
"azurerm_network_interface.web",
"azurerm_public_ip.web",
"azurerm_network_security_group.web_nic",
"azurerm_network_security_group.web_subnet"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_linux_virtual_machine.web",
"rationale": "azurerm_linux_virtual_machine.web has a public-IP path and the effective Azure NSG decisions across its subnet and network interface permit administrative access or all ports from internet sources. This exposes the guest to direct probing and credential attacks.",
"recommended_mitigation": "Remove the public IP where possible, restrict subnet and NIC NSG rules to expected client CIDRs and service ports, and use Azure Bastion, VPN, or Just-In-Time VM access for administration.",
"evidence": [
{
"key": "public_ip_path",
"values": [
"azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_public_ip.web (203.0.113.10)"
]
},
{
"key": "network_security_path",
"values": [
"azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_network_security_group.web_nic",
"azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_network_security_group.web_subnet"
]
},
{
"key": "network_security_rules",
"values": [
"azurerm_network_security_group.web_nic rule allow-ssh priority 200 allows tcp 22 from Internet",
"azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet"
]
},
{
"key": "public_exposure_reasons",
"values": [
"virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 1,
"blast_radius": 1,
"final_score": 4,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:d27bcfe0fe7dd0328e6b39cc723ca7f35744dcd35912c37aa5bbaea476862116",
"title": "Internet-exposed Azure virtual machine permits broad ingress",
"rule_id": "azure-public-compute-broad-ingress",
"category": "Spoofing",
"severity": "medium",
"affected_resources": [
"azurerm_windows_virtual_machine.admin",
"azurerm_network_interface.admin",
"azurerm_public_ip.admin",
"azurerm_network_security_group.admin_nic",
"azurerm_network_security_group.web_subnet"
],
"trust_boundary_id": "internet-to-service:internet->azurerm_windows_virtual_machine.admin",
"rationale": "azurerm_windows_virtual_machine.admin has a public-IP path and the effective Azure NSG decisions across its subnet and network interface permit administrative access or all ports from internet sources. This exposes the guest to direct probing and credential attacks.",
"recommended_mitigation": "Remove the public IP where possible, restrict subnet and NIC NSG rules to expected client CIDRs and service ports, and use Azure Bastion, VPN, or Just-In-Time VM access for administration.",
"evidence": [
{
"key": "public_ip_path",
"values": [
"azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_public_ip.admin (203.0.113.20)"
]
},
{
"key": "network_security_path",
"values": [
"azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_network_security_group.admin_nic",
"azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_network_security_group.web_subnet"
]
},
{
"key": "network_security_rules",
"values": [
"azurerm_network_security_group.admin_nic rule allow-rdp priority 200 allows tcp 3389 from Internet",
"azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet"
]
},
{
"key": "public_exposure_reasons",
"values": [
"virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress"
]
}
],
"severity_reasoning": {
"internet_exposure": 2,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 1,
"blast_radius": 1,
"final_score": 4,
"severity": "medium",
"computed_severity": null
}
},
{
"fingerprint": "sha256:2a44e989763aa27653d43c2bb1b509f369771831355d3184718a078ea506de07",
"title": "AKS Azure Policy add-on is not enabled",
"rule_id": "azure-aks-azure-policy-not-enabled",
"category": "Tampering",
"severity": "low",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not deterministically enable the Azure Policy add-on. Without the add-on, Kubernetes policy and governance controls may rely on external review instead of in-cluster policy enforcement.",
"recommended_mitigation": "Enable the Azure Policy add-on for AKS where policy-as-code enforcement, guardrails, or compliance reporting are expected for Kubernetes resources.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "azure_policy_posture",
"values": [
"azure_policy_state=unknown"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 1,
"severity": "low",
"computed_severity": null
}
},
{
"fingerprint": "sha256:4e874c6d1c7d4c50de4db71824b98468cf94f7c8efbb4768357bbd0edf0d18ed",
"title": "AKS RBAC posture is weak or not deterministic",
"rule_id": "azure-aks-rbac-posture-weak",
"category": "Elevation of Privilege",
"severity": "low",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform has weak or non-deterministic AKS RBAC posture. Kubernetes RBAC should be explicitly enabled, and Azure RBAC integration should not be disabled when the Azure Active Directory RBAC block is represented in the Terraform plan.",
"recommended_mitigation": "Enable Kubernetes RBAC explicitly, use Microsoft Entra ID integration for administrative access, and avoid disabling Azure RBAC integration when the cluster relies on Azure authorization controls.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "rbac_posture",
"values": [
"kubernetes_rbac_state=unknown",
"aad_rbac_state=not_configured",
"aad_managed_state=unknown",
"aad_azure_rbac_state=unknown",
"kubernetes RBAC state is unknown"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 1,
"data_sensitivity": 0,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 2,
"severity": "low",
"computed_severity": null
}
},
{
"fingerprint": "sha256:a7e8c693b82186cb583cd118ac7df4f9cc239fd93ae14f3a4c91ca5ae418bcc7",
"title": "AKS local accounts are not disabled",
"rule_id": "azure-aks-local-accounts-not-disabled",
"category": "Spoofing",
"severity": "low",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not deterministically disable AKS local accounts. Local cluster accounts can weaken centralized Microsoft Entra ID identity, auditing, and access control if they remain enabled.",
"recommended_mitigation": "Set `local_account_disabled` to `true`, use Microsoft Entra ID-backed authentication, and review any break-glass access paths separately.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "authentication_posture",
"values": [
"local_account_state=unknown"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 1,
"data_sensitivity": 0,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 2,
"severity": "low",
"computed_severity": null
}
},
{
"fingerprint": "sha256:4b2a8e462ccccb3a52616e1617299974dbfb0af24a5a919b302add975312f399",
"title": "AKS network policy is not configured",
"rule_id": "azure-aks-network-policy-missing",
"category": "Information Disclosure",
"severity": "low",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not have deterministic AKS network policy configured. Without a pod network policy provider, Kubernetes workloads have weaker pod-level traffic isolation and lateral-movement controls.",
"recommended_mitigation": "Configure an AKS network policy provider such as Azure, Cilium, or Calico, then define pod-level network policies for sensitive namespaces and workloads.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "network_policy_posture",
"values": [
"network_policy_state=unknown",
"network_policy is not represented in planned values"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 0,
"data_sensitivity": 0,
"lateral_movement": 1,
"blast_radius": 1,
"final_score": 2,
"severity": "low",
"computed_severity": null
}
},
{
"fingerprint": "sha256:cc04758506a87fc481399b7952f65316e056ce888a661f53df4ece8512420ea3",
"title": "AKS workload identity is not fully enabled",
"rule_id": "azure-aks-workload-identity-not-enabled",
"category": "Elevation of Privilege",
"severity": "low",
"affected_resources": [
"azurerm_kubernetes_cluster.platform"
],
"trust_boundary_id": null,
"rationale": "azurerm_kubernetes_cluster.platform does not deterministically enable AKS workload identity and its OIDC issuer. Pods may need to rely on broader node credentials, static secrets, or less auditable identity paths for Azure resource access.",
"recommended_mitigation": "Enable the AKS OIDC issuer and workload identity, bind Kubernetes service accounts to narrow managed identities, and avoid relying on node credentials or static secrets for Azure API access.",
"evidence": [
{
"key": "target_resource",
"values": [
"address=azurerm_kubernetes_cluster.platform",
"type=azurerm_kubernetes_cluster"
]
},
{
"key": "workload_identity_posture",
"values": [
"oidc_issuer_state=unknown",
"workload_identity_state=unknown"
]
}
],
"severity_reasoning": {
"internet_exposure": 0,
"privilege_breadth": 1,
"data_sensitivity": 0,
"lateral_movement": 0,
"blast_radius": 1,
"final_score": 2,
"severity": "low",
"computed_severity": null
}
}
],
"suppressed_findings": [],
"baselined_findings": [],
"observations": [
{
"title": "Azure managed identity principal is modeled",
"observation_id": "azure-managed-identity-principal-observed",
"affected_resources": [
"azurerm_linux_virtual_machine.web"
],
"rationale": "azurerm_linux_virtual_machine.web exposes a `UserAssigned` managed identity principal. Role assignments are connected only when principal IDs are known in the Terraform plan.",
"category": "iam",
"evidence": [
{
"key": "identity_type",
"values": [
"UserAssigned"
]
},
{
"key": "attached_identity_references",
"values": [
"azurerm_user_assigned_identity.deploy.id"
]
},
{
"key": "analysis_scope",
"values": [
"managed identity role assignments are connected when principal IDs are deterministic",
"transitive access findings are not emitted from managed identity assignments yet"
]
}
]
},
{
"title": "Azure managed identity principal is modeled",
"observation_id": "azure-managed-identity-principal-observed",
"affected_resources": [
"azurerm_user_assigned_identity.deploy"
],
"rationale": "azurerm_user_assigned_identity.deploy exposes a `UserAssigned` managed identity principal. Role assignments are connected only when principal IDs are known in the Terraform plan.",
"category": "iam",
"evidence": [
{
"key": "identity_type",
"values": [
"UserAssigned"
]
},
{
"key": "principal_id",
"values": [
"11111111-1111-1111-1111-111111111111"
]
},
{
"key": "client_id",
"values": [
"22222222-2222-2222-2222-222222222222"
]
},
{
"key": "tenant_id",
"values": [
"00000000-0000-0000-0000-000000000001"
]
},
{
"key": "analysis_scope",
"values": [
"managed identity role assignments are connected when principal IDs are deterministic",
"transitive access findings are not emitted from managed identity assignments yet"
]
}
]
},
{
"title": "Azure managed identity role assignment is connected",
"observation_id": "azure-managed-identity-role-assignment-observed",
"affected_resources": [
"azurerm_user_assigned_identity.deploy",
"azurerm_role_assignment.storage_owner"
],
"rationale": "azurerm_user_assigned_identity.deploy has Azure role assignments whose `principal_id` matches this managed identity. Scope breadth is reported separately from any downstream exposure rule.",
"category": "iam",
"evidence": [
{
"key": "role_assignment_sources",
"values": [
"azurerm_role_assignment.storage_owner"
]
},
{
"key": "role_definition_names",
"values": [
"Storage Blob Data Owner"
]
},
{
"key": "scopes",
"values": [
"azurerm_storage_account.logs.id"
]
},
{
"key": "scope_kinds",
"values": [
"resource"
]
},
{
"key": "target_resources",
"values": [
"azurerm_storage_account.logs"
]
},
{
"key": "breadth_signals",
"values": [
"broad_builtin_role",
"sensitive_resource_scope"
]
},
{
"key": "analysis_scope",
"values": [
"identity-to-role connection is modeled without inferring transitive data exposure"
]
}
]
}
],
"limitations": [
"Azure support covers a curated AzureRM set including Storage, Service Bus, Container Registry, Key Vault, SQL/PostgreSQL, App Service/Function Apps, AKS, networking and public edge, Private Endpoint/DNS-zone-group, diagnostic/Defender, and RBAC/identity posture. Remaining limitations include full Private DNS record correctness, broader RBAC hierarchy, MySQL, runtime application authentication and routing, full AKS node/workload posture, and unsupported platform services; analysis remains plan-local.",
"The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity."
]
}
Markdown report
# Azure Nightmare Plan Demo
- Analyzed file: `sample_azure_nightmare_plan.json`
- Provider: `azure`
- Normalized resources: `27`
- Unsupported resources: `0`
## Summary
This run identified **5 trust boundaries** and **36 findings** across **27 normalized resources**.
- High severity findings: `7`
- Medium severity findings: `24`
- Low severity findings: `5`
## Analysis Coverage
- Terraform resources seen: `27`
- Provider resources considered: `27`
- Normalized resources: `27`
- Unsupported resources: `0`
- Registered provider rules (Azure): `94`
- Enabled provider rules (Azure): `94`
- Disabled rules: `0`
- Severity overrides: `0`
- Unresolved in-plan references: `0`
- Findings by rule:
- `azure-public-compute-broad-ingress`: `2`
- `azure-nsg-flow-logs-not-configured`: `3`
- `azure-storage-container-public-access`: `3`
- `azure-storage-account-nested-public-access-enabled`: `2`
- `azure-storage-account-shared-key-enabled`: `2`
- `azure-storage-account-minimum-tls-below-1-2`: `2`
- `azure-storage-account-public-network-unrestricted`: `2`
- `azure-storage-account-missing-private-endpoint`: `2`
- `azure-key-vault-public-network-access`: `1`
- `azure-key-vault-missing-private-endpoint`: `1`
- `azure-key-vault-purge-protection-disabled`: `1`
- `azure-managed-identity-broad-rbac`: `1`
- `azure-public-workload-sensitive-resource-access`: `1`
- `azure-diagnostic-settings-missing`: `4`
- `azure-aks-api-server-public-unrestricted`: `1`
- `azure-aks-local-accounts-not-disabled`: `1`
- `azure-aks-rbac-posture-weak`: `1`
- `azure-aks-network-policy-missing`: `1`
- `azure-aks-workload-identity-not-enabled`: `1`
- `azure-aks-key-management-service-not-configured`: `1`
- `azure-aks-monitoring-agent-not-enabled`: `1`
- `azure-aks-defender-not-enabled`: `1`
- `azure-aks-azure-policy-not-enabled`: `1`
## Discovered Trust Boundaries
### `internet-to-service`
- Source: `internet`
- Target: `azurerm_storage_account.assets`
- Description: Traffic can cross from the public internet to azurerm_storage_account.assets.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.
### `internet-to-service`
- Source: `internet`
- Target: `azurerm_linux_virtual_machine.web`
- Description: Traffic can cross from the public internet to azurerm_linux_virtual_machine.web.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.
### `internet-to-service`
- Source: `internet`
- Target: `azurerm_storage_account.logs`
- Description: Traffic can cross from the public internet to azurerm_storage_account.logs.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.
### `internet-to-service`
- Source: `internet`
- Target: `azurerm_windows_virtual_machine.admin`
- Description: Traffic can cross from the public internet to azurerm_windows_virtual_machine.admin.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.
### `internet-to-service`
- Source: `internet`
- Target: `azurerm_key_vault.application`
- Description: Traffic can cross from the public internet to azurerm_key_vault.application.
- Rationale: The resource is directly reachable or intentionally exposed to unauthenticated network clients.
## Findings
### High
#### AKS control plane is public without narrow authorized IP ranges
- STRIDE category: Elevation of Privilege
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +1, data_sensitivity +0, lateral_movement +1, blast_radius +2, final_score 6 => high
- Rationale: azurerm_kubernetes_cluster.platform has AKS private cluster mode disabled and does not define narrow authorized IP ranges for the Kubernetes API server. The control plane is publicly reachable without a reviewed source range restriction.
- Recommended mitigation: Enable private cluster mode where possible, or configure `api_server_access_profile.authorized_ip_ranges` with narrow trusted CIDRs and avoid internet-wide source ranges.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- control plane posture: private_cluster_state=disabled; authorized_ip_ranges_state=not_configured; api_server_vnet_integration_state=unknown
#### Azure Storage account permits Shared Key authorization
- STRIDE category: Elevation of Privilege
- Affected resources: `azurerm_storage_account.assets`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +2, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 7 => high
- Rationale: azurerm_storage_account.assets permits Shared Key authorization. Account keys provide broad data-plane authority and are harder to constrain and attribute than Microsoft Entra ID identities.
- Recommended mitigation: Disable Shared Key authorization where supported, use Microsoft Entra ID and managed identities, and configure the AzureRM provider to use Azure AD for storage operations.
- Evidence:
- authorization posture: shared_access_key_enabled is true
#### Azure Storage account permits Shared Key authorization
- STRIDE category: Elevation of Privilege
- Affected resources: `azurerm_storage_account.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +2, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 7 => high
- Rationale: azurerm_storage_account.logs permits Shared Key authorization. Account keys provide broad data-plane authority and are harder to constrain and attribute than Microsoft Entra ID identities.
- Recommended mitigation: Disable Shared Key authorization where supported, use Microsoft Entra ID and managed identities, and configure the AzureRM provider to use Azure AD for storage operations.
- Evidence:
- authorization posture: shared_access_key_enabled is true
#### Azure Storage account permits nested public blob access
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.assets`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +1, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 6 => high
- Rationale: azurerm_storage_account.assets permits containers and blobs to opt into anonymous public access. This account-level setting allows a subordinate container configuration to expose stored data.
- Recommended mitigation: Set `allow_nested_items_to_be_public` to `false` so containers and blobs cannot opt into anonymous public access.
- Evidence:
- public access posture: allow_nested_items_to_be_public is true
#### Azure Storage account permits nested public blob access
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +1, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 6 => high
- Rationale: azurerm_storage_account.logs permits containers and blobs to opt into anonymous public access. This account-level setting allows a subordinate container configuration to expose stored data.
- Recommended mitigation: Set `allow_nested_items_to_be_public` to `false` so containers and blobs cannot opt into anonymous public access.
- Evidence:
- public access posture: allow_nested_items_to_be_public is true
#### Azure managed identity has broad RBAC authority
- STRIDE category: Elevation of Privilege
- Affected resources: `azurerm_user_assigned_identity.deploy`, `azurerm_role_assignment.storage_owner`, `azurerm_storage_account.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +3, data_sensitivity +2, lateral_movement +1, blast_radius +1, final_score 7 => high
- Rationale: azurerm_user_assigned_identity.deploy has Azure role assignments with broad scope or high-impact built-in roles. These grants expand what the managed identity can do if the workload or deployment path using it is compromised.
- Recommended mitigation: Replace broad managed identity role assignments with least-privilege resource-scoped roles, split deployment and runtime identities, and avoid subscription or resource-group scope unless required.
- Evidence:
- managed identity: address=azurerm_user_assigned_identity.deploy; identity_type=UserAssigned; principal_id=11111111-1111-1111-1111-111111111111; client_id=22222222-2222-2222-2222-222222222222
- role assignments: source=azurerm_role_assignment.storage_owner; role=Storage Blob Data Owner; scope=azurerm_storage_account.logs.id; scope_kind=resource; target=azurerm_storage_account.logs; signals=broad_builtin_role,sensitive_resource_scope
- breadth signals: broad_builtin_role; sensitive_resource_scope
- privileged access: grant_1=role=Storage Blob Data Owner; categories=data-admin; scope_kind=resource; confidence=high
- privilege categories: data-admin
#### Internet-exposed Azure workload can access sensitive resources
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_linux_virtual_machine.web`, `azurerm_user_assigned_identity.deploy`, `azurerm_role_assignment.storage_owner`, `azurerm_storage_account.logs`
- Trust boundary: `internet-to-service:internet->azurerm_linux_virtual_machine.web`
- Severity reasoning: internet_exposure +2, privilege_breadth +3, data_sensitivity +2, lateral_movement +1, blast_radius +2, final_score 10 => high
- Rationale: azurerm_user_assigned_identity.deploy is usable by an internet-exposed Azure workload and has a deterministic role assignment to a sensitive Azure resource. This creates a clear public workload to sensitive resource path if the workload identity is abused.
- Recommended mitigation: Remove direct internet exposure from the workload, restrict NSG ingress to trusted paths, and narrow the managed identity role assignment to the minimum sensitive resource operations required.
- Evidence:
- public workloads: address=azurerm_linux_virtual_machine.web; public_exposure=true; public_exposure_reasons=virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress
- managed identity: address=azurerm_user_assigned_identity.deploy; identity_type=UserAssigned; principal_id=11111111-1111-1111-1111-111111111111; client_id=22222222-2222-2222-2222-222222222222
- sensitive resource assignments: source=azurerm_role_assignment.storage_owner; role=Storage Blob Data Owner; scope=azurerm_storage_account.logs.id; scope_kind=resource; target=azurerm_storage_account.logs; signals=broad_builtin_role,sensitive_resource_scope
### Medium
#### AKS Defender coverage is not enabled
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +2, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_kubernetes_cluster.platform does not show deterministic Microsoft Defender for Containers coverage. Missing Defender signals can reduce runtime threat detection and security recommendations for AKS workloads.
- Recommended mitigation: Enable Microsoft Defender for Containers for AKS clusters that need runtime threat detection, vulnerability recommendations, and security posture monitoring.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- defender posture: defender_state=not_configured
#### AKS Key Management Service is not configured
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_kubernetes_cluster.platform does not show deterministic AKS Key Management Service configuration with a Key Vault key. Kubernetes secrets may not have customer-controlled encryption key ownership represented in the Terraform plan.
- Recommended mitigation: Configure AKS Key Management Service with a customer-managed Key Vault key for Kubernetes secrets where customer key ownership or stronger secrets encryption posture is required.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- secret encryption posture: key_management_service_state=not_configured; key_vault_key_id is not represented in planned values
#### AKS monitoring agent is not enabled
- STRIDE category: Repudiation
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +2, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_kubernetes_cluster.platform does not show deterministic AKS monitoring through the OMS agent and Log Analytics. Missing cluster telemetry can limit detection and investigation of control-plane and workload activity.
- Recommended mitigation: Enable the OMS agent or the current Azure Monitor integration for AKS and route cluster telemetry to a retained Log Analytics workspace or centralized logging pipeline.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- monitoring posture: oms_agent_state=not_configured; log_analytics_workspace_id is not represented in planned values
#### Azure Key Vault allows unrestricted public network access
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_key_vault.application`
- Trust boundary: `internet-to-service:internet->azurerm_key_vault.application`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_key_vault.application enables its public endpoint with an effective `Allow` network ACL default action. Network reachability does not itself grant data access, but it exposes the sensitive service endpoint to internet clients.
- Recommended mitigation: Disable public network access where possible, or configure Key Vault network ACLs with a default action of `Deny` and use reviewed subnets, IP ranges, or private endpoints.
- Evidence:
- network exposure: public_network_access_enabled is true; effective network_acls.default_action is Allow; network exposure is evaluated separately from identity authorization
#### Azure Key Vault lacks resolved private endpoint coverage
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_key_vault.application`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_key_vault.application does not have a resolved private endpoint and may allow public Key Vault data-plane access depending on firewall settings. This finding does not claim secret exposure; identity authorization is evaluated separately.
- Recommended mitigation: Add a Private Endpoint for the vault, verify data-plane clients use the private path, and explicitly disable public network access where possible.
- Evidence:
- target resource: address=azurerm_key_vault.application; type=azurerm_key_vault
- public network fallback: public_network_fallback_state=enabled; public_network_access_enabled is true
- private endpoint coverage: no resolved private endpoint targets this resource
- network acl posture: effective default_action is Allow
#### Azure Key Vault purge protection is disabled
- STRIDE category: Tampering
- Affected resources: `azurerm_key_vault.application`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_key_vault.application does not enable purge protection. A principal with sufficient deletion authority could permanently remove vault contents during the retention window.
- Recommended mitigation: Enable purge protection and retain soft-deleted vault objects long enough to recover from accidental or malicious deletion.
- Evidence:
- recovery posture: purge_protection_enabled is false
#### Azure Network Security Group lacks flow-log coverage
- STRIDE category: Repudiation
- Affected resources: `azurerm_network_security_group.web_subnet`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +2, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_network_security_group.web_subnet does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.
- Recommended mitigation: Configure an `azurerm_network_watcher_flow_log` for the NSG, route logs to durable storage, and keep retention long enough for incident response and network investigation workflows.
- Evidence:
- target network security group: address=azurerm_network_security_group.web_subnet; resource_type=azurerm_network_security_group; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-subnet; name=web-subnet
- flow log coverage: target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/web-subnet; target_nsg_identifier=azurerm_network_security_group.web_subnet; target_nsg_identifier=azurerm_network_security_group.web_subnet.id; target_nsg_identifier=web-subnet; resolved_nsg_flow_log_count=0; azurerm_network_watcher_flow_log resources are not modeled
#### Azure Network Security Group lacks flow-log coverage
- STRIDE category: Repudiation
- Affected resources: `azurerm_network_security_group.web_nic`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +2, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_network_security_group.web_nic does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.
- Recommended mitigation: Configure an `azurerm_network_watcher_flow_log` for the NSG, route logs to durable storage, and keep retention long enough for incident response and network investigation workflows.
- Evidence:
- target network security group: address=azurerm_network_security_group.web_nic; resource_type=azurerm_network_security_group; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/web-nic; name=web-nic
- flow log coverage: target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/web-nic; target_nsg_identifier=azurerm_network_security_group.web_nic; target_nsg_identifier=azurerm_network_security_group.web_nic.id; target_nsg_identifier=web-nic; resolved_nsg_flow_log_count=0; azurerm_network_watcher_flow_log resources are not modeled
#### Azure Network Security Group lacks flow-log coverage
- STRIDE category: Repudiation
- Affected resources: `azurerm_network_security_group.admin_nic`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +2, blast_radius +1, final_score 3 => medium
- Rationale: azurerm_network_security_group.admin_nic does not have a resolved azurerm_network_watcher_flow_log targeting the NSG in this Terraform plan. Network traffic metadata for incident response, threat hunting, and segmentation review may be unavailable unless NSG flow logs are configured elsewhere.
- Recommended mitigation: Configure an `azurerm_network_watcher_flow_log` for the NSG, route logs to durable storage, and keep retention long enough for incident response and network investigation workflows.
- Evidence:
- target network security group: address=azurerm_network_security_group.admin_nic; resource_type=azurerm_network_security_group; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Network/networkSecurityGroups/admin-nic; name=admin-nic
- flow log coverage: target_nsg_identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourcegroups/tfstride/providers/microsoft.network/networksecuritygroups/admin-nic; target_nsg_identifier=admin-nic; target_nsg_identifier=azurerm_network_security_group.admin_nic; target_nsg_identifier=azurerm_network_security_group.admin_nic.id; resolved_nsg_flow_log_count=0; azurerm_network_watcher_flow_log resources are not modeled
#### Azure Storage account allows TLS below 1.2
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.assets`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.assets accepts `TLS1_1` as its minimum protocol version. Deprecated TLS versions weaken transport protection for storage data-plane requests.
- Recommended mitigation: Set `min_tls_version` to `TLS1_2` and remove clients that require deprecated TLS versions.
- Evidence:
- transport posture: min_tls_version is TLS1_1
#### Azure Storage account allows TLS below 1.2
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.logs accepts `TLS1_0` as its minimum protocol version. Deprecated TLS versions weaken transport protection for storage data-plane requests.
- Recommended mitigation: Set `min_tls_version` to `TLS1_2` and remove clients that require deprecated TLS versions.
- Evidence:
- transport posture: min_tls_version is TLS1_0
#### Azure Storage account allows unrestricted public network access
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.assets`
- Trust boundary: `internet-to-service:internet->azurerm_storage_account.assets`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.assets enables its public network endpoint with an effective `Allow` default action. Storage data-plane endpoints are reachable without a default-deny network boundary.
- Recommended mitigation: Disable public network access where possible, or set the effective storage network default action to `Deny` and allow only reviewed subnets, IP ranges, or private endpoints.
- Evidence:
- network posture: public_network_access_enabled is true; effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.assets
#### Azure Storage account allows unrestricted public network access
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.logs`
- Trust boundary: `internet-to-service:internet->azurerm_storage_account.logs`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.logs enables its public network endpoint with an effective `Allow` default action. Storage data-plane endpoints are reachable without a default-deny network boundary.
- Recommended mitigation: Disable public network access where possible, or set the effective storage network default action to `Deny` and allow only reviewed subnets, IP ranges, or private endpoints.
- Evidence:
- network posture: public_network_access_enabled is true; effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.logs
#### Azure Storage account lacks resolved private endpoint coverage
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.assets`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.assets does not have a resolved private endpoint and may remain reachable through public Azure Storage data-plane endpoints. Network rules can reduce exposure, but they are not equivalent to private-endpoint-only access unless public network fallback is disabled.
- Recommended mitigation: Add a Private Endpoint for the required storage subresources, verify clients use private paths, and explicitly disable public network access where possible.
- Evidence:
- target resource: address=azurerm_storage_account.assets; type=azurerm_storage_account
- public network fallback: public_network_fallback_state=enabled; public_network_access_enabled is true
- private endpoint coverage: no resolved private endpoint targets this resource
- network acl posture: effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.assets
#### Azure Storage account lacks resolved private endpoint coverage
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.logs does not have a resolved private endpoint and may remain reachable through public Azure Storage data-plane endpoints. Network rules can reduce exposure, but they are not equivalent to private-endpoint-only access unless public network fallback is disabled.
- Recommended mitigation: Add a Private Endpoint for the required storage subresources, verify clients use private paths, and explicitly disable public network access where possible.
- Evidence:
- target resource: address=azurerm_storage_account.logs; type=azurerm_storage_account
- public network fallback: public_network_fallback_state=enabled; public_network_access_enabled is true
- private endpoint coverage: no resolved private endpoint targets this resource
- network acl posture: effective default_action is Allow; network rule source is azurerm_storage_account_network_rules.logs
#### Azure Storage container is publicly accessible
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.assets`, `azurerm_storage_container.public_assets`
- Trust boundary: `internet-to-service:internet->azurerm_storage_account.assets`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_container.public_assets permits anonymous `blob` access through a storage account that allows nested public access and unrestricted public network reachability.
- Recommended mitigation: Set the container access type to `private`, disable nested public access on the storage account, and use scoped identities or time-limited access mechanisms for intentional object sharing.
- Evidence:
- public exposure reasons: container_access_type is blob; azurerm_storage_account.assets allows nested items to be public; azurerm_storage_account.assets is reachable through its public network endpoint
#### Azure Storage container is publicly accessible
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.logs`, `azurerm_storage_container.public_logs`
- Trust boundary: `internet-to-service:internet->azurerm_storage_account.logs`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_container.public_logs permits anonymous `container` access through a storage account that allows nested public access and unrestricted public network reachability.
- Recommended mitigation: Set the container access type to `private`, disable nested public access on the storage account, and use scoped identities or time-limited access mechanisms for intentional object sharing.
- Evidence:
- public exposure reasons: container_access_type is container; azurerm_storage_account.logs allows nested items to be public; azurerm_storage_account.logs is reachable through its public network endpoint
#### Azure Storage container is publicly accessible
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_storage_account.logs`, `azurerm_storage_container.public_backups`
- Trust boundary: `internet-to-service:internet->azurerm_storage_account.logs`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_container.public_backups permits anonymous `blob` access through a storage account that allows nested public access and unrestricted public network reachability.
- Recommended mitigation: Set the container access type to `private`, disable nested public access on the storage account, and use scoped identities or time-limited access mechanisms for intentional object sharing.
- Evidence:
- public exposure reasons: container_access_type is blob; azurerm_storage_account.logs allows nested items to be public; azurerm_storage_account.logs is reachable through its public network endpoint
#### Azure resource lacks diagnostic settings
- STRIDE category: Repudiation
- Affected resources: `azurerm_storage_account.assets`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.assets has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Recommended mitigation: Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.
- Evidence:
- target resource: address=azurerm_storage_account.assets; type=azurerm_storage_account; name=tfstridepublicassets; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepublicassets
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
#### Azure resource lacks diagnostic settings
- STRIDE category: Repudiation
- Affected resources: `azurerm_storage_account.logs`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_storage_account.logs has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Recommended mitigation: Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.
- Evidence:
- target resource: address=azurerm_storage_account.logs; type=azurerm_storage_account; name=tfstridepubliclogs; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.Storage/storageAccounts/tfstridepubliclogs
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
#### Azure resource lacks diagnostic settings
- STRIDE category: Repudiation
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +1, lateral_movement +1, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_kubernetes_cluster.platform has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Recommended mitigation: Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster; name=tfstride-platform; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.ContainerService/managedClusters/tfstride-platform
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
#### Azure resource lacks diagnostic settings
- STRIDE category: Repudiation
- Affected resources: `azurerm_key_vault.application`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +2, lateral_movement +0, blast_radius +1, final_score 5 => medium
- Rationale: azurerm_key_vault.application has no resolved Azure Monitor diagnostic setting in this Terraform plan. Security-relevant data-plane, control-plane, or platform logs may not be routed to a retained logging destination for investigation and alerting.
- Recommended mitigation: Add an Azure Monitor diagnostic setting for the resource and route security-relevant logs and metrics to a retained Log Analytics workspace, storage account, Event Hub, or approved partner destination.
- Evidence:
- target resource: address=azurerm_key_vault.application; type=azurerm_key_vault; name=tfstride-application; identifier=/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/tfstride/providers/Microsoft.KeyVault/vaults/tfstride-application
- diagnostic coverage: no resolved azurerm_monitor_diagnostic_setting targets this resource
#### Internet-exposed Azure virtual machine permits broad ingress
- STRIDE category: Spoofing
- Affected resources: `azurerm_linux_virtual_machine.web`, `azurerm_network_interface.web`, `azurerm_public_ip.web`, `azurerm_network_security_group.web_nic`, `azurerm_network_security_group.web_subnet`
- Trust boundary: `internet-to-service:internet->azurerm_linux_virtual_machine.web`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +0, lateral_movement +1, blast_radius +1, final_score 4 => medium
- Rationale: azurerm_linux_virtual_machine.web has a public-IP path and the effective Azure NSG decisions across its subnet and network interface permit administrative access or all ports from internet sources. This exposes the guest to direct probing and credential attacks.
- Recommended mitigation: Remove the public IP where possible, restrict subnet and NIC NSG rules to expected client CIDRs and service ports, and use Azure Bastion, VPN, or Just-In-Time VM access for administration.
- Evidence:
- public ip path: azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_public_ip.web (203.0.113.10)
- network security path: azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_network_security_group.web_nic; azurerm_linux_virtual_machine.web -> azurerm_network_interface.web -> azurerm_network_security_group.web_subnet
- network security rules: azurerm_network_security_group.web_nic rule allow-ssh priority 200 allows tcp 22 from Internet; azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet
- public exposure reasons: virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress
#### Internet-exposed Azure virtual machine permits broad ingress
- STRIDE category: Spoofing
- Affected resources: `azurerm_windows_virtual_machine.admin`, `azurerm_network_interface.admin`, `azurerm_public_ip.admin`, `azurerm_network_security_group.admin_nic`, `azurerm_network_security_group.web_subnet`
- Trust boundary: `internet-to-service:internet->azurerm_windows_virtual_machine.admin`
- Severity reasoning: internet_exposure +2, privilege_breadth +0, data_sensitivity +0, lateral_movement +1, blast_radius +1, final_score 4 => medium
- Rationale: azurerm_windows_virtual_machine.admin has a public-IP path and the effective Azure NSG decisions across its subnet and network interface permit administrative access or all ports from internet sources. This exposes the guest to direct probing and credential attacks.
- Recommended mitigation: Remove the public IP where possible, restrict subnet and NIC NSG rules to expected client CIDRs and service ports, and use Azure Bastion, VPN, or Just-In-Time VM access for administration.
- Evidence:
- public ip path: azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_public_ip.admin (203.0.113.20)
- network security path: azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_network_security_group.admin_nic; azurerm_windows_virtual_machine.admin -> azurerm_network_interface.admin -> azurerm_network_security_group.web_subnet
- network security rules: azurerm_network_security_group.admin_nic rule allow-rdp priority 200 allows tcp 3389 from Internet; azurerm_network_security_group.web_subnet rule allow-internet-tcp priority 300 allows tcp 0-65535 from Internet
- public exposure reasons: virtual machine has a public IP path and effective subnet/NIC NSG decisions allow internet ingress
### Low
#### AKS Azure Policy add-on is not enabled
- STRIDE category: Tampering
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +0, blast_radius +1, final_score 1 => low
- Rationale: azurerm_kubernetes_cluster.platform does not deterministically enable the Azure Policy add-on. Without the add-on, Kubernetes policy and governance controls may rely on external review instead of in-cluster policy enforcement.
- Recommended mitigation: Enable the Azure Policy add-on for AKS where policy-as-code enforcement, guardrails, or compliance reporting are expected for Kubernetes resources.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- azure policy posture: azure_policy_state=unknown
#### AKS RBAC posture is weak or not deterministic
- STRIDE category: Elevation of Privilege
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +1, data_sensitivity +0, lateral_movement +0, blast_radius +1, final_score 2 => low
- Rationale: azurerm_kubernetes_cluster.platform has weak or non-deterministic AKS RBAC posture. Kubernetes RBAC should be explicitly enabled, and Azure RBAC integration should not be disabled when the Azure Active Directory RBAC block is represented in the Terraform plan.
- Recommended mitigation: Enable Kubernetes RBAC explicitly, use Microsoft Entra ID integration for administrative access, and avoid disabling Azure RBAC integration when the cluster relies on Azure authorization controls.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- rbac posture: kubernetes_rbac_state=unknown; aad_rbac_state=not_configured; aad_managed_state=unknown; aad_azure_rbac_state=unknown; kubernetes RBAC state is unknown
#### AKS local accounts are not disabled
- STRIDE category: Spoofing
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +1, data_sensitivity +0, lateral_movement +0, blast_radius +1, final_score 2 => low
- Rationale: azurerm_kubernetes_cluster.platform does not deterministically disable AKS local accounts. Local cluster accounts can weaken centralized Microsoft Entra ID identity, auditing, and access control if they remain enabled.
- Recommended mitigation: Set `local_account_disabled` to `true`, use Microsoft Entra ID-backed authentication, and review any break-glass access paths separately.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- authentication posture: local_account_state=unknown
#### AKS network policy is not configured
- STRIDE category: Information Disclosure
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +0, data_sensitivity +0, lateral_movement +1, blast_radius +1, final_score 2 => low
- Rationale: azurerm_kubernetes_cluster.platform does not have deterministic AKS network policy configured. Without a pod network policy provider, Kubernetes workloads have weaker pod-level traffic isolation and lateral-movement controls.
- Recommended mitigation: Configure an AKS network policy provider such as Azure, Cilium, or Calico, then define pod-level network policies for sensitive namespaces and workloads.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- network policy posture: network_policy_state=unknown; network_policy is not represented in planned values
#### AKS workload identity is not fully enabled
- STRIDE category: Elevation of Privilege
- Affected resources: `azurerm_kubernetes_cluster.platform`
- Trust boundary: `not-applicable`
- Severity reasoning: internet_exposure +0, privilege_breadth +1, data_sensitivity +0, lateral_movement +0, blast_radius +1, final_score 2 => low
- Rationale: azurerm_kubernetes_cluster.platform does not deterministically enable AKS workload identity and its OIDC issuer. Pods may need to rely on broader node credentials, static secrets, or less auditable identity paths for Azure resource access.
- Recommended mitigation: Enable the AKS OIDC issuer and workload identity, bind Kubernetes service accounts to narrow managed identities, and avoid relying on node credentials or static secrets for Azure API access.
- Evidence:
- target resource: address=azurerm_kubernetes_cluster.platform; type=azurerm_kubernetes_cluster
- workload identity posture: oidc_issuer_state=unknown; workload_identity_state=unknown
## Controls Observed
### Azure managed identity principal is modeled
- Category: `iam`
- Affected resources: `azurerm_linux_virtual_machine.web`
- Rationale: azurerm_linux_virtual_machine.web exposes a `UserAssigned` managed identity principal. Role assignments are connected only when principal IDs are known in the Terraform plan.
- Evidence:
- identity type: UserAssigned
- attached identity references: azurerm_user_assigned_identity.deploy.id
- analysis scope: managed identity role assignments are connected when principal IDs are deterministic; transitive access findings are not emitted from managed identity assignments yet
### Azure managed identity principal is modeled
- Category: `iam`
- Affected resources: `azurerm_user_assigned_identity.deploy`
- Rationale: azurerm_user_assigned_identity.deploy exposes a `UserAssigned` managed identity principal. Role assignments are connected only when principal IDs are known in the Terraform plan.
- Evidence:
- identity type: UserAssigned
- principal id: 11111111-1111-1111-1111-111111111111
- client id: 22222222-2222-2222-2222-222222222222
- tenant id: 00000000-0000-0000-0000-000000000001
- analysis scope: managed identity role assignments are connected when principal IDs are deterministic; transitive access findings are not emitted from managed identity assignments yet
### Azure managed identity role assignment is connected
- Category: `iam`
- Affected resources: `azurerm_user_assigned_identity.deploy`, `azurerm_role_assignment.storage_owner`
- Rationale: azurerm_user_assigned_identity.deploy has Azure role assignments whose `principal_id` matches this managed identity. Scope breadth is reported separately from any downstream exposure rule.
- Evidence:
- role assignment sources: azurerm_role_assignment.storage_owner
- role definition names: Storage Blob Data Owner
- scopes: azurerm_storage_account.logs.id
- scope kinds: resource
- target resources: azurerm_storage_account.logs
- breadth signals: broad_builtin_role; sensitive_resource_scope
- analysis scope: identity-to-role connection is modeled without inferring transitive data exposure
## Limitations / Unsupported Resources
- Azure support covers a curated AzureRM set including Storage, Service Bus, Container Registry, Key Vault, SQL/PostgreSQL, App Service/Function Apps, AKS, networking and public edge, Private Endpoint/DNS-zone-group, diagnostic/Defender, and RBAC/identity posture. Remaining limitations include full Private DNS record correctness, broader RBAC hierarchy, MySQL, runtime application authentication and routing, full AKS node/workload posture, and unsupported platform services; analysis remains plan-local.
- The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity.
Limits
Unsupported or intentionally scoped areas
- Azure support covers a curated AzureRM set including Storage, Service Bus, Container Registry, Key Vault, SQL/PostgreSQL, App Service/Function Apps, AKS, networking and public edge, Private Endpoint/DNS-zone-group, diagnostic/Defender, and RBAC/identity posture. Remaining limitations include full Private DNS record correctness, broader RBAC hierarchy, MySQL, runtime application authentication and routing, full AKS node/workload posture, and unsupported platform services; analysis remains plan-local.
- The engine reasons over Terraform planned values only and does not validate runtime drift, CloudTrail evidence, or post-deploy control-plane activity.