Built-in scenario

azure/sample_azure_nightmare_plan.json

Azure Nightmare Plan Demo

Analyzed sample_azure_nightmare_plan.json with 27 normalized resources and 5 trust boundaries.

Analyze another plan

Active findings

36

Trust boundaries

5

Resources

27

Observations

3
High 7
Medium 24
Low 5

Analysis coverage

Audit trail for this run

Terraform resources 27
Unsupported 0
Enabled rules 94
Unresolved refs 0

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

7

AKS control plane is public without narrow authorized IP ranges

azure-aks-api-server-public-unrestricted

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.

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-enabled

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.

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-enabled

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.

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-enabled

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.

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-enabled

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.

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-rbac

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.

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-access

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.

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

24

AKS Defender coverage is not enabled

azure-aks-defender-not-enabled

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.

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-configured

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.

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-enabled

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.

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-access

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.

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-endpoint

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.

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-disabled

azurerm_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-configured

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.

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-configured

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.

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-configured

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.

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-2

azurerm_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-2

azurerm_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-unrestricted

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.

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-unrestricted

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.

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-endpoint

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.

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-endpoint

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.

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-access

azurerm_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-access

azurerm_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-access

azurerm_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-missing

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.

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-missing

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.

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-missing

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.

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-missing

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.

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-ingress

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.

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-ingress

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.

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

5

AKS Azure Policy add-on is not enabled

azure-aks-azure-policy-not-enabled

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.

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-weak

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.

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-disabled

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.

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-missing

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.

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-enabled

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.

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.

azurerm_linux_virtual_machine.web

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.

azurerm_user_assigned_identity.deploy

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.

azurerm_user_assigned_identity.deploy, azurerm_role_assignment.storage_owner

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.