Built-in scenario

azure/sample_azure_plan.json

Azure Inventory Demo

Analyzed sample_azure_plan.json with 15 normalized resources and 3 trust boundaries.

Analyze another plan

Active findings

24

Trust boundaries

3

Resources

15

Observations

0
High 3
Medium 16
Low 5

Analysis coverage

Audit trail for this run

Terraform resources 15
Unsupported 0
Enabled rules 94
Unresolved refs 0

Resource coverage

Provider resources considered
15
Normalized resources
15

No unsupported Azure resource types were encountered.

Rule coverage

Registered rules
94
Disabled rules
0
  • azure-public-compute-broad-ingress1
  • azure-nsg-flow-logs-not-configured2
  • azure-storage-container-public-access1
  • azure-storage-account-nested-public-access-enabled1
  • azure-storage-account-shared-key-enabled1
  • azure-storage-account-minimum-tls-below-1-21
  • azure-storage-account-public-network-unrestricted1
  • azure-storage-account-missing-private-endpoint1
  • azure-key-vault-public-network-access1
  • azure-key-vault-missing-private-endpoint1
  • azure-key-vault-purge-protection-disabled1
  • azure-diagnostic-settings-missing3
  • 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

3

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

Medium

16

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

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

No observations were recorded for this plan.

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.

Raw outputs

Stable contract and markdown

JSON report
{
  "kind": "tfstride-report",
  "version": "1.1",
  "tool": {
    "name": "tfstride",
    "version": "0.4.23"
  },
  "title": "Azure Inventory Demo",
  "analyzed_file": "sample_azure_plan.json",
  "analyzed_path": "sample_azure_plan.json",
  "summary": {
    "normalized_resources": 15,
    "unsupported_resources": 0,
    "trust_boundaries": 3,
    "active_findings": 24,
    "total_findings": 24,
    "suppressed_findings": 0,
    "baselined_findings": 0,
    "severity_counts": {
      "high": 3,
      "medium": 16,
      "low": 5
    }
  },
  "filtering": {
    "total_findings": 24,
    "active_findings": 24,
    "suppressed_findings": 0,
    "baselined_findings": 0,
    "suppressions_path": null,
    "baseline_path": null
  },
  "analysis_coverage": {
    "resources": {
      "total_resources": 15,
      "provider_resources": 15,
      "normalized_resources": 15,
      "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": 1,
        "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": 2,
        "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": 1,
        "azure-storage-account-nested-public-access-enabled": 1,
        "azure-storage-account-shared-key-enabled": 1,
        "azure-storage-account-minimum-tls-below-1-2": 1,
        "azure-storage-account-public-network-unrestricted": 1,
        "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": 1,
        "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": 0,
        "azure-federated-identity-privileged-access": 0,
        "azure-public-workload-sensitive-resource-access": 0,
        "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": 3,
        "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": 15,
      "provider_resource_count": 15,
      "normalized_resource_count": 15,
      "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"
          ],
          "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.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.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.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_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.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_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_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_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_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_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"
          ]
        }
      }
    ]
  },
  "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."
    }
  ],
  "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: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: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: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: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: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: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: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: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: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": [],
  "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 Inventory Demo

- Analyzed file: `sample_azure_plan.json`
- Provider: `azure`
- Normalized resources: `15`
- Unsupported resources: `0`

## Summary

This run identified **3 trust boundaries** and **24 findings** across **15 normalized resources**.

- High severity findings: `3`
- Medium severity findings: `16`
- Low severity findings: `5`

## Analysis Coverage

- Terraform resources seen: `15`
- Provider resources considered: `15`
- Normalized resources: `15`
- 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`: `1`
  - `azure-nsg-flow-logs-not-configured`: `2`
  - `azure-storage-container-public-access`: `1`
  - `azure-storage-account-nested-public-access-enabled`: `1`
  - `azure-storage-account-shared-key-enabled`: `1`
  - `azure-storage-account-minimum-tls-below-1-2`: `1`
  - `azure-storage-account-public-network-unrestricted`: `1`
  - `azure-storage-account-missing-private-endpoint`: `1`
  - `azure-key-vault-public-network-access`: `1`
  - `azure-key-vault-missing-private-endpoint`: `1`
  - `azure-key-vault-purge-protection-disabled`: `1`
  - `azure-diagnostic-settings-missing`: `3`
  - `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_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 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

### 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 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 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 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 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 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_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

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

## 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.