---
title: Azure
url: /docs/reference/pre-built-policy-packs/iso-27001/azure/
---This page lists all 158 policies in the **ISO/IEC 27001:2022** pack for **Azure**, as published in `iso-27001-azure` version `1.0.0`.

## Policies by control

**A.5.9 Inventory of information and other associated assets** — An inventory of information and other associated assets, including owners, shall be developed and maintained.

- [managed-disk-unused](#managed-disk-unused)
- [resources-cost-management-tags](#resources-cost-management-tags)
- [resources-environment-tags](#resources-environment-tags)
- [vnet-nsg-unused](#vnet-nsg-unused)
- [vnet-public-ip-associated](#vnet-public-ip-associated)

**A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.

- [api-management-tls](#api-management-tls)
- [app-service-disable-ftp](#app-service-disable-ftp)
- [app-service-https-only](#app-service-https-only)
- [application-gateway-https-redirection](#application-gateway-https-redirection)
- [application-gateway-tls](#application-gateway-tls)
- [front-door-tls](#front-door-tls)
- [function-public-access](#function-public-access)
- [load-balancer-https-listeners](#load-balancer-https-listeners)
- [mysql-ssl-enforcement](#mysql-ssl-enforcement)
- [nsg-http-restriction](#nsg-http-restriction)
- [postgresql-ssl-enforcement](#postgresql-ssl-enforcement)
- [redis-cache-non-ssl-port](#redis-cache-non-ssl-port)
- [sql-server-encrypted-connections](#sql-server-encrypted-connections)
- [storage-account-https-only](#storage-account-https-only)
- [storage-account-minimum-tls](#storage-account-minimum-tls)

**A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.

- [aad-custom-roles](#aad-custom-roles)
- [aad-direct-user-roles](#aad-direct-user-roles)
- [aad-role-assignments](#aad-role-assignments)
- [aad-role-no-wildcard-assignments](#aad-role-no-wildcard-assignments)
- [key-vault-access-policies](#key-vault-access-policies)
- [keyvault-rbac-least-privilege](#keyvault-rbac-least-privilege)
- [rbac-least-privilege](#rbac-least-privilege)
- [sql-database-least-privilege](#sql-database-least-privilege)
- [storage-account-least-privilege](#storage-account-least-privilege)
- [storage-account-policy-grantee](#storage-account-policy-grantee)

**A.5.16 Identity management** — The full life cycle of identities shall be managed.

- [aks-azure-ad-integration](#aks-azure-ad-integration)
- [hdinsight-kerberos-enabled](#hdinsight-kerberos-enabled)
- [sql-server-azure-ad-authentication](#sql-server-azure-ad-authentication)
- [storage-account-shared-key-access](#storage-account-shared-key-access)
- [vm-managed-identity](#vm-managed-identity)
- [web-app-auth-settings](#web-app-auth-settings)

**A.5.17 Authentication information** — Allocation and management of authentication information shall be controlled by a management process, including advising personnel on appropriate handling of authentication information.

- [aks-secret-encryption](#aks-secret-encryption)
- [prohibit-hardcoded-secrets](#prohibit-hardcoded-secrets)
- [vm-managed-identity](#vm-managed-identity)

**A.5.18 Access rights** — Access rights to information and other associated assets shall be provisioned, reviewed, modified and removed in accordance with the organization's topic-specific policy on and rules for access control.

- [aad-direct-user-roles](#aad-direct-user-roles)
- [storage-account-policy-grantee](#storage-account-policy-grantee)

**A.5.33 Protection of records** — Records shall be protected from loss, destruction, falsification, unauthorized access and unauthorized release.

- [activity-log-encryption-enabled](#activity-log-encryption-enabled)
- [activity-log-multi-region-trail-enabled](#activity-log-multi-region-trail-enabled)
- [event-hubs-retention](#event-hubs-retention)
- [key-vault-purge-protection](#key-vault-purge-protection)
- [key-vault-soft-delete](#key-vault-soft-delete)

**A.6.7 Remote working** — Security measures shall be implemented when personnel are working remotely to protect information accessed, processed or stored outside the organization's premises.

- [nsg-restrict-ingress-ssh-all](#nsg-restrict-ingress-ssh-all)
- [nsg-ssh-rdp-restriction](#nsg-ssh-rdp-restriction)

**A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

- [aad-custom-roles](#aad-custom-roles)
- [aad-global-admin-no-permanent-access](#aad-global-admin-no-permanent-access)
- [aad-role-assignments](#aad-role-assignments)
- [aad-role-no-wildcard-assignments](#aad-role-no-wildcard-assignments)
- [container-instance-privileged-mode](#container-instance-privileged-mode)
- [key-vault-access-policies](#key-vault-access-policies)
- [keyvault-rbac-least-privilege](#keyvault-rbac-least-privilege)
- [rbac-least-privilege](#rbac-least-privilege)
- [sql-database-least-privilege](#sql-database-least-privilege)
- [storage-account-least-privilege](#storage-account-least-privilege)
- [storage-account-policy-grantee](#storage-account-policy-grantee)

**A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

- [aks-private-clusters](#aks-private-clusters)
- [cosmos-db-private-endpoints](#cosmos-db-private-endpoints)
- [dms-instance-public-access](#dms-instance-public-access)
- [function-public-access](#function-public-access)
- [hdinsight-cluster-public-access](#hdinsight-cluster-public-access)
- [key-vault-network-access](#key-vault-network-access)
- [managed-disk-snapshot-restrict-network-access](#managed-disk-snapshot-restrict-network-access)
- [managed-disk-snapshot-restrict-public-access](#managed-disk-snapshot-restrict-public-access)
- [ml-compute-instance-cmk-configured](#ml-compute-instance-cmk-configured)
- [ml-compute-internet-access](#ml-compute-internet-access)
- [mysql-private-endpoints](#mysql-private-endpoints)
- [network-interface-no-public-ip](#network-interface-no-public-ip)
- [nsg-disallow-public-internet-ingress](#nsg-disallow-public-internet-ingress)
- [postgresql-private-endpoints](#postgresql-private-endpoints)
- [redis-cache-private-endpoints](#redis-cache-private-endpoints)
- [search-service-vnet-only](#search-service-vnet-only)
- [sql-server-disable-public-access](#sql-server-disable-public-access)
- [storage-account-firewall](#storage-account-firewall)
- [storage-account-public-access](#storage-account-public-access)
- [storage-account-public-network-access](#storage-account-public-network-access)
- [synapse-public-network-access](#synapse-public-network-access)
- [vm-no-public-ip](#vm-no-public-ip)
- [vm-scale-set-no-public-ip](#vm-scale-set-no-public-ip)

**A.8.5 Secure authentication** — Secure authentication technologies and procedures shall be implemented based on information access restrictions and the topic-specific policy on access control.

- [aks-azure-ad-integration](#aks-azure-ad-integration)
- [hdinsight-kerberos-enabled](#hdinsight-kerberos-enabled)
- [sql-server-azure-ad-authentication](#sql-server-azure-ad-authentication)
- [storage-account-shared-key-access](#storage-account-shared-key-access)
- [web-app-auth-settings](#web-app-auth-settings)

**A.8.6 Capacity management** — The use of resources shall be monitored and adjusted in line with current and expected capacity requirements.

- [cosmos-db-autoscaling-enabled](#cosmos-db-autoscaling-enabled)

**A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

- [aks-auto-upgrade](#aks-auto-upgrade)
- [app-service-managed-updates](#app-service-managed-updates)
- [security-center-enabled](#security-center-enabled)
- [update-management-compliance](#update-management-compliance)
- [update-management-maintenance-configuration](#update-management-maintenance-configuration)
- [update-management-patch-compliant](#update-management-patch-compliant)
- [vm-scale-set-automatic-os-upgrades](#vm-scale-set-automatic-os-upgrades)

**A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

- [app-service-disable-ftp](#app-service-disable-ftp)
- [container-instance-privileged-mode](#container-instance-privileged-mode)
- [custom-image-validation](#custom-image-validation)
- [load-balancer-deletion-protection](#load-balancer-deletion-protection)
- [resources-change-tracking-tags](#resources-change-tracking-tags)
- [subscription-part-of-management-groups](#subscription-part-of-management-groups)
- [vm-approved-images](#vm-approved-images)
- [vm-requires-managed-disks](#vm-requires-managed-disks)
- [vm-scale-set-require-managed-disks](#vm-scale-set-require-managed-disks)

**A.8.12 Data leakage prevention** — Data leakage prevention measures shall be applied to systems, networks and any other devices that process, store or transmit sensitive information.

- [sql-server-restrict-outbound-access](#sql-server-restrict-outbound-access)
- [synapse-data-exfiltration-protection](#synapse-data-exfiltration-protection)

**A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

- [backup-instance-configuration](#backup-instance-configuration)
- [blob-service-lifecycle](#blob-service-lifecycle)
- [cosmos-db-backup-policies](#cosmos-db-backup-policies)
- [cosmos-db-pitr-enabled](#cosmos-db-pitr-enabled)
- [key-vault-soft-delete](#key-vault-soft-delete)
- [managed-disk-backup-protection-exists](#managed-disk-backup-protection-exists)
- [snapshot-configuration](#snapshot-configuration)
- [sql-database-backup-retention](#sql-database-backup-retention)
- [storage-account-versioning-enabled](#storage-account-versioning-enabled)
- [synapse-backup-enabled](#synapse-backup-enabled)

**A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

- [activity-log-multi-region-trail-enabled](#activity-log-multi-region-trail-enabled)
- [aks-node-pools-vm-scale-sets](#aks-node-pools-vm-scale-sets)
- [application-gateway-multi-az](#application-gateway-multi-az)
- [load-balancer-cross-zone-enabled](#load-balancer-cross-zone-enabled)
- [load-balancer-multi-az](#load-balancer-multi-az)
- [sql-database-high-availability](#sql-database-high-availability)
- [storage-account-geo-replication](#storage-account-geo-replication)
- [storage-account-replication-enabled](#storage-account-replication-enabled)
- [storage-account-versioning-enabled](#storage-account-versioning-enabled)
- [vm-scale-set-multi-az](#vm-scale-set-multi-az)

**A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

- [activity-log-encryption-enabled](#activity-log-encryption-enabled)
- [activity-log-file-integrity-enabled](#activity-log-file-integrity-enabled)
- [activity-log-monitor-integration](#activity-log-monitor-integration)
- [activity-log-monitoring](#activity-log-monitoring)
- [activity-log-security-trail-enabled](#activity-log-security-trail-enabled)
- [activity-log-storage-dataevents](#activity-log-storage-dataevents)
- [activity-log-trail-enabled](#activity-log-trail-enabled)
- [api-management-diagnostic-settings-exist](#api-management-diagnostic-settings-exist)
- [cdn-distribution-logging-enabled](#cdn-distribution-logging-enabled)
- [diagnostic-setting-configuration](#diagnostic-setting-configuration)
- [flow-log-configuration](#flow-log-configuration)
- [load-balancer-logging](#load-balancer-logging)
- [log-analytics-retention](#log-analytics-retention)
- [search-service-logs-monitor](#search-service-logs-monitor)
- [sql-server-audit-logging](#sql-server-audit-logging)
- [synapse-configuration-logging](#synapse-configuration-logging)
- [vm-detailed-monitoring](#vm-detailed-monitoring)
- [vnet-flow-logs-enabled](#vnet-flow-logs-enabled)
- [wafv2-logging-enabled](#wafv2-logging-enabled)

**A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

- [activity-log-monitor-integration](#activity-log-monitor-integration)
- [activity-log-monitoring](#activity-log-monitoring)
- [activity-log-trail-enabled](#activity-log-trail-enabled)
- [application-gateway-has-health-probes](#application-gateway-has-health-probes)
- [azure-firewall-threat-intelligence](#azure-firewall-threat-intelligence)
- [defender-for-cloud-enabled](#defender-for-cloud-enabled)
- [diagnostic-setting-configuration](#diagnostic-setting-configuration)
- [load-balancer-health-probes](#load-balancer-health-probes)
- [search-service-logs-monitor](#search-service-logs-monitor)
- [security-center-enabled](#security-center-enabled)
- [vm-detailed-monitoring](#vm-detailed-monitoring)
- [vmss-load-balancer-healthcheck-required](#vmss-load-balancer-healthcheck-required)
- [wafv2-logging-enabled](#wafv2-logging-enabled)

**A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

- [aks-network-policies](#aks-network-policies)
- [aks-private-clusters](#aks-private-clusters)
- [application-gateway-waf](#application-gateway-waf)
- [azure-firewall-threat-intelligence](#azure-firewall-threat-intelligence)
- [cosmos-db-private-endpoints](#cosmos-db-private-endpoints)
- [function-public-access](#function-public-access)
- [function-vnet-integration](#function-vnet-integration)
- [hdinsight-cluster-public-access](#hdinsight-cluster-public-access)
- [key-vault-key-not-scheduled-for-deletion](#key-vault-key-not-scheduled-for-deletion)
- [key-vault-network-access](#key-vault-network-access)
- [ml-compute-instance-cmk-configured](#ml-compute-instance-cmk-configured)
- [network-interface-no-public-ip](#network-interface-no-public-ip)
- [no-unrestricted-route-to-internet-gateway](#no-unrestricted-route-to-internet-gateway)
- [nsg-disallow-public-internet-ingress](#nsg-disallow-public-internet-ingress)
- [nsg-http-restriction](#nsg-http-restriction)
- [nsg-restrict-ingress-ssh-all](#nsg-restrict-ingress-ssh-all)
- [nsg-ssh-rdp-restriction](#nsg-ssh-rdp-restriction)
- [nsg-strict-rules](#nsg-strict-rules)
- [redis-cache-private-endpoints](#redis-cache-private-endpoints)
- [search-service-vnet-only](#search-service-vnet-only)
- [sql-server-disable-public-access](#sql-server-disable-public-access)
- [storage-account-firewall](#storage-account-firewall)
- [storage-account-public-network-access](#storage-account-public-network-access)
- [subnet-auto-assign-public-ip](#subnet-auto-assign-public-ip)
- [synapse-public-network-access](#synapse-public-network-access)
- [vm-in-vnet](#vm-in-vnet)
- [vm-no-public-ip](#vm-no-public-ip)
- [vm-scale-set-no-public-ip](#vm-scale-set-no-public-ip)
- [vnet-ddos-protection](#vnet-ddos-protection)
- [vnet-nsg-associated-to-nic](#vnet-nsg-associated-to-nic)

**A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.

- [aks-network-policies](#aks-network-policies)
- [dms-instance-public-access](#dms-instance-public-access)
- [function-vnet-integration](#function-vnet-integration)
- [no-unrestricted-route-to-internet-gateway](#no-unrestricted-route-to-internet-gateway)
- [synapse-data-exfiltration-protection](#synapse-data-exfiltration-protection)
- [vm-in-vnet](#vm-in-vnet)

**A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

- [activity-log-encryption-enabled](#activity-log-encryption-enabled)
- [aks-secret-encryption](#aks-secret-encryption)
- [api-management-tls](#api-management-tls)
- [app-service-https-only](#app-service-https-only)
- [application-gateway-https-redirection](#application-gateway-https-redirection)
- [application-gateway-tls](#application-gateway-tls)
- [container-registry-customer-managed-keys](#container-registry-customer-managed-keys)
- [cosmos-db-customer-managed-keys](#cosmos-db-customer-managed-keys)
- [data-factory-customer-managed-keys](#data-factory-customer-managed-keys)
- [event-hubs-customer-managed-keys](#event-hubs-customer-managed-keys)
- [front-door-tls](#front-door-tls)
- [function-app-customer-managed-keys](#function-app-customer-managed-keys)
- [hdinsight-cluster-public-access](#hdinsight-cluster-public-access)
- [key-vault-key-configuration](#key-vault-key-configuration)
- [key-vault-key-lifecycle](#key-vault-key-lifecycle)
- [key-vault-key-not-scheduled-for-deletion](#key-vault-key-not-scheduled-for-deletion)
- [key-vault-key-rotation](#key-vault-key-rotation)
- [key-vault-purge-protection](#key-vault-purge-protection)
- [load-balancer-https-listeners](#load-balancer-https-listeners)
- [managed-disk-attached-encryption-enabled](#managed-disk-attached-encryption-enabled)
- [managed-disk-customer-managed-keys](#managed-disk-customer-managed-keys)
- [ml-workspace-cmk-configured](#ml-workspace-cmk-configured)
- [mysql-customer-managed-keys](#mysql-customer-managed-keys)
- [mysql-ssl-enforcement](#mysql-ssl-enforcement)
- [postgresql-customer-managed-keys](#postgresql-customer-managed-keys)
- [postgresql-ssl-enforcement](#postgresql-ssl-enforcement)
- [redis-cache-non-ssl-port](#redis-cache-non-ssl-port)
- [redis-cache-private-endpoints](#redis-cache-private-endpoints)
- [search-service-encrypted-at-rest](#search-service-encrypted-at-rest)
- [service-bus-customer-managed-keys](#service-bus-customer-managed-keys)
- [snapshot-configuration](#snapshot-configuration)
- [sql-database-customer-managed-keys](#sql-database-customer-managed-keys)
- [sql-database-tde-enabled-check](#sql-database-tde-enabled-check)
- [sql-server-encrypted-connections](#sql-server-encrypted-connections)
- [storage-account-files-encryption](#storage-account-files-encryption)
- [storage-account-https-only](#storage-account-https-only)
- [storage-account-infrastructure-encryption](#storage-account-infrastructure-encryption)
- [storage-account-minimum-tls](#storage-account-minimum-tls)
- [storage-account-uses-customer-managed-keys](#storage-account-uses-customer-managed-keys)
- [storage-file-encrypted-check](#storage-file-encrypted-check)
- [synapse-workspace-customer-managed-keys](#synapse-workspace-customer-managed-keys)

## Policy details

### aad-custom-roles

**Severity:** high · **Enforcement:** advisory

Prevent Azure AD custom roles and Azure Native custom role definitions with broad permissions.

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Remove Broad Permissions from Custom Roles

##### To pass this policy:
- Replace wildcard (*) actions with specific permissions
- Remove forbidden actions (Microsoft.Authorization/*, Microsoft.Resources/*)
- Keep total actions under 50 (or configured limit)

##### Fix for Azure Native Custom Roles

```typescript
new azure.authorization.RoleDefinition("custom-role", {
    roleName: "Storage Manager",
    roleType: "CustomRole",
    assignableScopes: [`/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`],
    permissions: [{
        actions: [
            "Microsoft.Storage/storageAccounts/read",
            "Microsoft.Storage/storageAccounts/write",
            "Microsoft.Storage/storageAccounts/listKeys/action",
        ], // Specific actions only, no wildcards
        notActions: [],
    }],
});
```

##### Fix for Azure AD Custom Roles

```typescript
new azuread.CustomDirectoryRole("custom-aad-role", {
    displayName: "User Support Specialist",
    enabled: true,
    permissions: [{
        allowedResourceActions: [
            "microsoft.directory/users/password/update",
            "microsoft.directory/users/usageLocation/update",
            "microsoft.directory/users/userPrincipalName/update",
        ], // Specific actions only, no wildcards
    }],
});
```

### aad-direct-user-roles

**Severity:** high · **Enforcement:** advisory

Prevent Azure AD users from having direct role assignments.

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.5.18 Access rights** — Access rights to information and other associated assets shall be provisioned, reviewed, modified and removed in accordance with the organization's topic-specific policy on and rules for access control.

Remediation

##### Fix: Use Group-Based Role Assignments

##### To pass this policy:
- Assign roles to Azure AD groups, not individual users
- Set principalType to "Group" instead of "User"

```typescript
// Create a security group
const devGroup = new azuread.Group("dev-team", {
    displayName: "Development Team",
    securityEnabled: true,
});

// Assign role to the group (not to users directly)
new azure.authorization.RoleAssignment("group-role", {
    principalId: devGroup.id,
    principalType: "Group", // Must be Group, not User
    roleDefinitionId: contributorRoleId,
    scope: resourceGroupScope,
});

// Add users as group members
new azuread.GroupMember("dev-member", {
    groupObjectId: devGroup.id,
    memberObjectId: userObjectId,
});
```

### aad-global-admin-no-permanent-access

**Severity:** high · **Enforcement:** advisory

Manage default global administrator accounts to prevent permanent privileged access.

- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Remove Permanent Global Administrator Access

##### To pass this policy:
- Add conditions to Global Admin assignments (condition & conditionVersion properties)
- Never assign Global Admin to Service Principals

```typescript
// BAD: Permanent Global Administrator assignment without conditions
new azure.authorization.RoleAssignment("permanent-global-admin", {
    principalId: userId,
    principalType: "User",
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
    scope: "/",
});

// GOOD: Conditional assignment
new azure.authorization.RoleAssignment("conditional-global-admin", {
    principalId: groupId,
    principalType: "Group", // Use groups, not individual users
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
    scope: "/subscriptions/${subscriptionId}", // Limit scope when possible
    condition: "@Resource[Microsoft.Authorization/roleAssignments:principalId] StringEquals '${groupId}'",
    conditionVersion: "2.0",
});
```

##### Use Azure Native PIM Resources (When Available)

Configure time-bounded eligible role assignments:

```typescript
// Create PIM Role Eligibility Schedule
new azure.authorization.RoleEligibilitySchedule("global-admin-eligible", {
    scope: "/subscriptions/${subscriptionId}",
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
    principalId: groupId,
    principalType: "Group",
    expirationDate: "2024-12-31T23:59:59Z", // Must have expiration
    startDate: "2024-01-01T00:00:00Z",
});
```

##### Use Azure AD Privileged Access Groups

Configure privileged access through Azure AD groups with eligibility schedules:

```typescript
// Create a privileged access group
const privilegedAdminGroup = new azuread.Group("privileged-admins", {
    displayName: "Privileged Global Administrators",
    securityEnabled: true,
});

// Create eligibility schedule for the group
new azuread.PrivilegedAccessGroupEligibilitySchedule("admin-eligibility", {
    groupId: privilegedAdminGroup.objectId,
    principalId: userId,
    assignmentType: "member",
    duration: "PT8H", // 8-hour eligibility window
    justification: "Required for quarterly security audit",
    startDate: "2024-01-01T00:00:00Z",
    permanentAssignment: false, // Never permanent
});
```

##### Implement Break-Glass Accounts with Monitoring

Create dedicated emergency access accounts with proper alerts:

```typescript
// Create a break-glass security group
const breakGlassGroup = new azuread.Group("break-glass-admins", {
    displayName: "Emergency Break-Glass Administrators",
    securityEnabled: true,
});

// Assign Global Admin to break-glass group (permanent but monitored)
new azure.authorization.RoleAssignment("break-glass-admin", {
    principalId: breakGlassGroup.objectId,
    principalType: "Group",
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
    scope: "/",
});

// Create activity log alert for break-glass usage
new azure.insights.ActivityLogAlert("break-glass-usage-alert", {
    resourceGroupName: securityResourceGroup.name,
    location: "Global",
    enabled: true,
    condition: {
        allOf: [{
            field: "category",
            equals: "Administrative",
        }, {
            field: "caller",
            contains: breakGlassGroup.objectId.apply(id => id),
        }],
    },
    actions: [{
        actionGroupId: securityAlertActionGroup.id,
    }],
});
```

##### Use Least Privilege Alternatives

Consider using more specific admin roles instead of Global Administrator:

```typescript
// Instead of Global Administrator, use specific roles
const specificAdminRoles = {
    userAdmin: "fe930be7-5e62-47db-91af-98c3a49a38b1",
    securityAdmin: "194ae4cb-b126-40b2-bd5b-6091b380977d",
    cloudAppAdmin: "158c047a-c907-4556-b7ef-446551a6b5f7",
    conditionalAccessAdmin: "b1be1c3e-b65d-4f19-8427-f6fa0d97feb9",
};

// Assign only the specific role needed
new azure.authorization.RoleAssignment("security-admin-limited", {
    principalId: securityTeamGroupId,
    principalType: "Group",
    roleDefinitionId: `/providers/Microsoft.Authorization/roleDefinitions/${specificAdminRoles.securityAdmin}`,
    scope: "/subscriptions/${subscriptionId}",
});
```

##### Service Principals Should Never Have Global Admin

```typescript
// BAD: Service Principal with Global Admin
new azure.authorization.RoleAssignment("sp-global-admin", {
    principalId: servicePrincipalId,
    principalType: "ServicePrincipal",
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/62e90394-69f5-4237-9190-012177145e10",
    scope: "/",
});

// GOOD: Service Principal with specific, scoped permissions
new azure.authorization.RoleAssignment("sp-contributor", {
    principalId: servicePrincipalId,
    principalType: "ServicePrincipal",
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", // Contributor
    scope: "/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}",
});
```

### aad-role-assignments

**Severity:** high · **Enforcement:** advisory

Prevent Azure AD and Azure Native role assignments with excessive privileges.

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Remove Excessive Role Assignment Privileges

- Avoid forbidden roles (Owner, User Access Administrator)
- Don't use overly broad scopes (root "/" or all subscriptions)
- Assign roles to groups instead of individual users

```typescript
// GOOD: Specific role, scoped to resource group, assigned to group
new azure.authorization.RoleAssignment("good-assignment", {
    principalId: securityGroupId,
    principalType: "Group",
    roleDefinitionId: "/subscriptions/${subscriptionId}/providers/Microsoft.Authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c", // Contributor
    scope: `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`,
});
```

### aad-role-no-wildcard-assignments

**Severity:** high · **Enforcement:** advisory

Restrict administrator privileges - no wildcard role assignments.

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Remove Wildcard or Overly Broad Role Assignments

##### To pass this policy:
- Avoid root "/" or "/subscriptions" scopes
- Don't use wildcards (*) or "all" in scopes
- Scope assignments to resource groups or specific resources
- Service Principals must have narrow scopes (resource-level)
- Add conditions for subscription-level assignments
```typescript
// GOOD: Resource group scoped
new azure.authorization.RoleAssignment("specific-scope", {
    principalId: groupId,
    principalType: "Group",
    roleDefinitionId: contributorRoleId,
    scope: `/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}`,
});

// GOOD: Subscription-level with conditions
new azure.authorization.RoleAssignment("conditional-broad", {
    principalId: groupId,
    roleDefinitionId: readerRoleId,
    scope: `/subscriptions/${subscriptionId}`,
    condition: "@Resource[Microsoft.Storage/storageAccounts:name] StringStartsWith 'dev'",
    conditionVersion: "2.0",
});
```

### activity-log-encryption-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Activity Log encryption is enabled for data protection.

- **A.5.33 Protection of records** — Records shall be protected from loss, destruction, falsification, unauthorized access and unauthorized release.
- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Activity Log Encryption

Your Activity Log data needs encryption both at rest and in transit to protect audit trail integrity.

**Configure Storage Account with encryption for Activity Log destination:**

```typescript
const logStorage = new azure.storage.StorageAccount("activityLogStorage", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "Standard_GRS" },
    kind: "StorageV2",
    enableHttpsTrafficOnly: true,  // Required: HTTPS-only for encryption in transit
    minimumTlsVersion: "TLS1_2",   // Required: Minimum TLS 1.2
    encryption: {
        services: {
            blob: {
                enabled: true,  // Required: Blob encryption at rest
                keyType: "Account",
            },
            file: {
                enabled: true,
            },
        },
        keySource: "Microsoft.Storage",  // Or "Microsoft.Keyvault" for customer-managed keys
    },
});
```

**For customer-managed keys, integrate with Key Vault:**

```typescript
const logStorage = new azure.storage.StorageAccount("activityLogStorage", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "Standard_GRS" },
    kind: "StorageV2",
    enableHttpsTrafficOnly: true,
    minimumTlsVersion: "TLS1_2",
    encryption: {
        services: {
            blob: { enabled: true, keyType: "Account" },
        },
        keySource: "Microsoft.Keyvault",  // Use customer-managed keys
        keyVaultProperties: {
            keyName: encryptionKey.name,
            keyVaultUri: keyVault.properties.vaultUri,
        },
    },
});
```

**Configure Activity Log diagnostic settings with encrypted destination:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
    name: "activity-log-encrypted",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,  // Log Analytics (encrypted by default)
    storageAccountId: logStorage.id,  // Encrypted Storage Account
    logs: [
        { category: "Administrative", enabled: true },
        { category: "Security", enabled: true },
    ],
});
```

**Note:** Encryption requirements per CIS Controls v8 IG1 4.6:
- **At rest**: Storage accounts must have blob encryption enabled
- **In transit**: Storage accounts must enforce HTTPS-only traffic with TLS 1.2+
- **Customer-managed keys**: Optional but recommended for additional control

Log Analytics workspaces use Azure-managed encryption by default.

### activity-log-file-integrity-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Activity Log file integrity monitoring is enabled for security monitoring.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable Activity Log File Integrity Monitoring

Your Activity Log diagnostic settings need file integrity monitoring configured to detect tampering with audit logs.

**Configure Activity Log diagnostic settings with file integrity monitoring:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
    name: "activity-log-to-workspace",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,
    logs: [
        { category: "Administrative", enabled: true },
        { category: "Security", enabled: true },
        { category: "Alert", enabled: true },
        { category: "Policy", enabled: true },
    ],
});
```

**Apply tags to the Log Analytics Workspace to indicate file integrity monitoring:**

```typescript
const workspace = new azure.operationalinsights.Workspace("securityWorkspace", {
    // ... other properties
    tags: {
        FileIntegrity: "enabled",              // File integrity monitoring enabled
        HashValidation: "sha256",              // Hash-based integrity validation
        IntegrityAlerting: "enabled",          // Alerts on integrity violations
    },
});
```

**For Storage Account destinations, apply tags to indicate immutable storage:**

```typescript
const logStorage = new azure.storage.StorageAccount("logStorage", {
    // ... other properties
    tags: {
        ImmutableStorage: "enabled",
        WORMCompliance: "enabled",
        TamperProof: "enabled",
    },
});
```

**Note:** DiagnosticSetting resources do NOT support tags. Apply tags to the destination resources (Log Analytics Workspace or Storage Account) to indicate file integrity monitoring is configured per CIS Controls v8 IG1 4.6. Immutable storage prevents log tampering and ensures audit trail integrity.

### activity-log-monitor-integration

**Severity:** medium · **Enforcement:** advisory

Ensure Activity Log is integrated with advanced monitoring solutions for comprehensive log analysis.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Configure Activity Log Advanced Monitor Integration

Your Activity Log needs integration with advanced monitoring solutions for comprehensive log analysis and threat detection.

**Set up Activity Log diagnostic settings with Log Analytics workspace:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
    name: "activity-log-advanced-monitoring",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,  // Link to Log Analytics workspace
    eventHubAuthorizationRuleId: eventHubRule.id,  // Optional: for real-time processing
    logs: [
        { category: "Administrative", enabled: true },
        { category: "Security", enabled: true },
        { category: "ServiceHealth", enabled: true },
        { category: "Alert", enabled: true },
        { category: "Recommendation", enabled: true },
        { category: "Policy", enabled: true },
        { category: "Autoscale", enabled: true },
        { category: "ResourceHealth", enabled: true },
    ],
    metrics: [
        { category: "AllMetrics", enabled: true },
    ],
});
```

**Configure Log Analytics workspace with advanced analytics tags:**

```typescript
const workspace = new azure.operationalinsights.Workspace("securityWorkspace", {
    // ... other properties
    retentionInDays: 730,  // Advanced analytics requires longer retention
    tags: {
        AdvancedAnalytics: "enabled",
        KQLQueries: "enabled",
        Workbooks: "enabled",
        MachineLearning: "enabled",
        AnomalyDetection: "enabled",
    },
});
```

**Create alert rules for proactive monitoring:**

```typescript
const securityAlert = new azure.monitor.ActivityLogAlert("securityAlert", {
    // ... configure alerts for critical security events
    tags: {
        ActivityLogBased: "true",
        SecurityMonitoring: "enabled",
        ThreatDetection: "enabled",
    },
});
```

**Note:** DiagnosticSetting resources do NOT support tags. Apply tags to the destination resources (Log Analytics Workspace, Activity Log Alerts, etc.) to indicate monitoring capabilities. This enables sophisticated log analysis, correlation, and real-time threat detection per CIS Controls v8 IG3 3.14.

### activity-log-monitoring

**Severity:** medium · **Enforcement:** advisory

Ensure Activity Log monitoring is properly configured.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable Activity Log Monitoring Integration

Your Activity Log needs to send data to a monitoring solution for centralized audit trail visibility.

**Configure Activity Log diagnostic settings:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
    name: "activity-log-monitoring",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,  // Required: Log Analytics workspace
    storageAccountId: storageAccount.id,  // Optional: for long-term retention
    logs: [
        { category: "Administrative", enabled: true },
        { category: "Security", enabled: true },
        { category: "Alert", enabled: true },
        { category: "Policy", enabled: true },
    ],
    retentionPolicy: {
        enabled: true,
        days: 365,  // Minimum 365 days recommended
    },
});
```

**Ensure a Log Analytics workspace exists:**

```typescript
const workspace = new azure.operationalinsights.Workspace("monitoringWorkspace", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "PerGB2018" },
    retentionInDays: 365,
});
```

**Note:** Activity Log monitoring provides audit trail visibility and enables security analysis per CIS Controls v8 IG2 3.8. Include all critical log categories (Administrative, Security, Alert, Policy) for comprehensive monitoring.

### activity-log-multi-region-trail-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Activity Log multi-region trail is enabled for resilience and compliance.

- **A.5.33 Protection of records** — Records shall be protected from loss, destruction, falsification, unauthorized access and unauthorized release.
- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Configure Activity Log Multi-Region Trail

Your Activity Log needs to send data to destinations in multiple regions for disaster recovery and business continuity.

**Deploy Log Analytics workspaces in multiple regions:**

```typescript
const workspaceEast = new azure.operationalinsights.Workspace("workspaceEast", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "PerGB2018" },
    retentionInDays: 365,
});

const workspaceWest = new azure.operationalinsights.Workspace("workspaceWest", {
    resourceGroupName: resourceGroup.name,
    location: "westus2",  // Geographically redundant region
    sku: { name: "PerGB2018" },
    retentionInDays: 365,
});
```

**Configure Activity Log to send to primary workspace:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
    name: "activity-log-multi-region",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspaceEast.id,  // Primary region
    storageAccountId: storageWest.id,  // Secondary region for redundancy
    logs: [
        { category: "Administrative", enabled: true },
        { category: "Security", enabled: true },
        { category: "Alert", enabled: true },
        { category: "Policy", enabled: true },
    ],
});
```

**Recommended region pairs:**
- East US + West US 2
- East US 2 + Central US
- North Europe + West Europe
- Southeast Asia + East Asia

**Note:** Multi-region configuration ensures audit logs remain available during regional outages per CIS Controls v8 IG1 4.6. Deploy Activity Log destinations in at least 2 geographically redundant regions.

### activity-log-security-trail-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Activity Log security trail is enabled for security monitoring and compliance.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable Activity Log Security Trail

Your Activity Log needs to capture security events and administrative actions for compliance and security monitoring.

**Configure Activity Log diagnostic settings with security categories:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogSecurityTrail", {
    name: "activity-log-security-trail",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,  // Send to Log Analytics workspace
    storageAccountId: storageAccount.id,  // Optional: for archival
    logs: [
        { category: "Security", enabled: true },         // Required: Security events
        { category: "Administrative", enabled: true },   // Required: Admin actions
        { category: "Policy", enabled: true },           // Policy evaluation events
        { category: "Alert", enabled: true },            // Alert events
    ],
    retentionPolicy: {
        enabled: true,
        days: 365,  // Minimum 365 days for security trail
    },
});
```

**Ensure at least one destination is configured:**

```typescript
// Option 1: Log Analytics workspace (recommended)
const workspace = new azure.operationalinsights.Workspace("securityWorkspace", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "PerGB2018" },
    retentionInDays: 365,
});

// Option 2: Storage Account for archival
const storageAccount = new azure.storage.StorageAccount("securityLogs", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "Standard_GRS" },
    kind: "StorageV2",
});

// Option 3: Event Hub for real-time processing
const eventHub = new azure.eventhub.EventHub("securityEvents", {
    // ... configure Event Hub
});
```

**Note:** Security trail captures security-relevant events including authentication, authorization, resource changes, and policy violations per CIS Controls v8 IG1 4.1. Both Security and Administrative categories are required for comprehensive audit trails.

### activity-log-storage-dataevents

**Severity:** medium · **Enforcement:** advisory

Ensure Activity Log captures Storage Account data events for comprehensive log analysis.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable Storage Account Data Events Logging

Your Storage Accounts need data plane diagnostic settings to capture data access events for comprehensive log analysis.

**Configure diagnostic settings for Storage Account blob service:**

```typescript
const blobDiagnostic = new azure.monitor.DiagnosticSetting("blobDataEvents", {
    name: "blob-data-events",
    resourceUri: pulumi.interpolate`${storageAccount.id}/blobServices/default`,
    workspaceId: workspace.id,  // Send to Log Analytics
    logs: [
        { category: "StorageRead", enabled: true },
        { category: "StorageWrite", enabled: true },
        { category: "StorageDelete", enabled: true },
    ],
    metrics: [
        { category: "Transaction", enabled: true },
    ],
});
```

**Tag your Storage Account to indicate data event logging:**

```typescript
const storageAccount = new azure.storage.StorageAccount("myStorage", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    tags: {
        DataEventLogging: "enabled",
        StorageDataEvents: "enabled",
        AuditDataAccess: "enabled",
    },
});
```

**Configure Activity Log to capture subscription-level storage events:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogDiag", {
    name: "activity-log-storage-events",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,
    logs: [
        { category: "Administrative", enabled: true },  // Captures storage account management operations
        { category: "Security", enabled: true },
    ],
    retentionPolicy: {
        enabled: true,
        days: 365,
    },
});
```

**Optional: Configure Event Grid for real-time storage events:**

```typescript
const eventSubscription = new azure.eventgrid.EventSubscription("storageEvents", {
    scope: storageAccount.id,
    destination: {
        endpointType: "eventhub",
        // ... configure destination
    },
    filter: {
        includedEventTypes: [
            "Microsoft.Storage.BlobCreated",
            "Microsoft.Storage.BlobDeleted",
        ],
    },
});
```

**Note:** Data plane logging captures individual blob read/write/delete operations. This provides comprehensive audit trails for data access monitoring per CIS Controls v8 IG3 3.14. Configure for blob, file, table, and queue services as needed.

### activity-log-trail-enabled

**Severity:** high · **Enforcement:** advisory

Collect audit logs from Activity Log trails.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable Activity Log Trail Collection

Your subscription needs Activity Log diagnostic settings configured to collect comprehensive audit trails.

**Configure Activity Log diagnostic settings at subscription level:**

```typescript
const activityLogDiagnostic = new azure.monitor.DiagnosticSetting("activityLogTrail", {
    name: "activity-log-audit-trail",
    resourceUri: pulumi.interpolate`/subscriptions/${subscriptionId}`,
    workspaceId: workspace.id,  // Required: Log Analytics workspace
    storageAccountId: storageAccount.id,  // Optional: for long-term archival
    eventHubAuthorizationRuleId: eventHubRule.id,  // Optional: for real-time streaming
    logs: [
        { category: "Administrative", enabled: true },
        { category: "Security", enabled: true },
        { category: "Alert", enabled: true },
        { category: "Policy", enabled: true },
        { category: "Recommendation", enabled: true },
        { category: "ResourceHealth", enabled: true },
        { category: "ServiceHealth", enabled: true },
        { category: "Autoscale", enabled: true },
    ],
    metrics: [
        { category: "AllMetrics", enabled: true },
    ],
    retentionPolicy: {
        enabled: true,
        days: 365,  // Minimum 365 days recommended
    },
});
```

**Create required destination resources:**

```typescript
// Log Analytics workspace for analysis
const workspace = new azure.operationalinsights.Workspace("auditWorkspace", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "PerGB2018" },
    retentionInDays: 365,
});

// Storage Account for archival (optional)
const storageAccount = new azure.storage.StorageAccount("auditLogs", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    sku: { name: "Standard_GRS" },
    kind: "StorageV2",
});
```

**Optional: Configure Activity Log alerts for critical events:**

```typescript
const criticalAlert = new azure.monitor.ActivityLogAlert("criticalEvents", {
    resourceGroupName: resourceGroup.name,
    scopes: [pulumi.interpolate`/subscriptions/${subscriptionId}`],
    condition: {
        allOf: [
            { field: "category", equals: "Security" },
            { field: "level", equals: "Critical" },
        ],
    },
    actions: {
        actionGroups: [actionGroup.id],
    },
});
```

**Note:** Activity Log trails provide comprehensive audit logs for all subscription-level activities per CIS Controls v8 IG1 8.2. Enable all relevant categories and configure at least one destination (Log Analytics, Storage Account, or Event Hub).

### aks-auto-upgrade

**Severity:** high · **Enforcement:** advisory

Require AKS clusters to have auto-upgrade enabled

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

Remediation

##### Fix: Enable Auto-Upgrade for AKS Cluster

```typescript
const aksCluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
    dnsPrefix: "myaks",
    autoUpgradeProfile: {
        upgradeChannel: "stable",       // Set to 'stable', 'patch', or 'rapid'
        nodeOSUpgradeChannel: "NodeImage",  // Enable node OS auto-upgrade
    },
    // ... other config
});
```

### aks-azure-ad-integration

**Severity:** high · **Enforcement:** advisory

Require AKS clusters to use Azure AD integration

- **A.5.16 Identity management** — The full life cycle of identities shall be managed.
- **A.8.5 Secure authentication** — Secure authentication technologies and procedures shall be implemented based on information access restrictions and the topic-specific policy on access control.

Remediation

##### Fix: Enable AKS Azure AD Integration

```typescript
const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
    enableRBAC: true,  // Required for Azure AD
    aadProfile: {
        managed: true,  // Enable managed Azure AD integration
        enableAzureRBAC: true,  // Optional: Azure RBAC for Kubernetes
    },
    disableLocalAccounts: true,  // Disable local accounts for enhanced security
    // ... other config
});
```

### aks-network-policies

**Severity:** high · **Enforcement:** advisory

Require AKS clusters to have network policies enabled

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.

Remediation

##### Fix: Enable AKS Network Policies

```typescript
const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
    networkProfile: {
        networkPlugin: "azure",  // Azure CNI recommended
        networkPolicy: "calico",  // Enable network policy (calico, azure, or cilium)
    },
    // ... other config
});
```

### aks-node-pools-vm-scale-sets

**Severity:** high · **Enforcement:** advisory

Require AKS node pools to use VM Scale Sets

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Configure AKS Node Pools to Use VM Scale Sets

```typescript
const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
    agentPoolProfiles: [{
        name: "nodepool1",
        vmSize: "Standard_DS2_v2",
        type: "VirtualMachineScaleSets",  // Use VM Scale Sets for availability
        // ... other config
    }],
    // ... other config
});
```

### aks-private-clusters

**Severity:** high · **Enforcement:** advisory

Require AKS clusters to be private clusters

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Configure AKS as a Private Cluster

```typescript
const aksCluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
    apiServerAccessProfile: {
        enablePrivateCluster: true,  // Enable private cluster mode
        privateDNSZone: "system",  // Use system-managed private DNS zone
        enablePrivateClusterPublicFQDN: false,  // Disable public FQDN
    },
    // ... other config
});
```

### aks-secret-encryption

**Severity:** high · **Enforcement:** advisory

Require AKS clusters to have secret encryption enabled

- **A.5.17 Authentication information** — Allocation and management of authentication information shall be controlled by a management process, including advising personnel on appropriate handling of authentication information.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable AKS Secret Encryption with Azure Key Vault

```typescript
const cluster = new azurenative.containerservice.ManagedCluster("my-aks-cluster", {
    addonProfiles: {
        azureKeyvaultSecretsProvider: {
            enabled: true,  // Enable Azure Key Vault Secrets Provider
            config: {
                enableSecretRotation: "true",  // Enable secret rotation
                rotationPollInterval: "2m",  // Set rotation interval
            },
        },
    },
    // ... other config
});
```

### api-management-diagnostic-settings-exist

**Severity:** medium · **Enforcement:** advisory

Ensure API Management has diagnostic settings configured (existence check).

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable Execution Logging for API Management

Your API Management service needs advanced execution logging. Configure detailed logging with Log Analytics:

```typescript
const diagnostics = new azure.insights.DiagnosticSetting("apimExecutionLogs", {
    name: "apim-execution-diagnostics",
    resourceUri: apimService.id,
    workspaceId: logAnalyticsWorkspace.id,
    logs: [
        {
            category: "GatewayLogs",  // Request/response execution logs
            enabled: true,
            retentionPolicy: { enabled: true, days: 365 },
        },
        {
            category: "WebSocketConnectionLogs",  // WebSocket execution
            enabled: true,
            retentionPolicy: { enabled: true, days: 365 },
        },
    ],
    metrics: [{
        category: "AllMetrics",  // Performance metrics
        enabled: true,
    }],
});
```

**Note**: This policy checks that diagnostic settings exist. Use the 'diagnostic-setting-configuration' resource policy to validate the configuration details of diagnostic settings.

### api-management-tls

**Severity:** high · **Enforcement:** advisory

Require API Management to have secure TLS/SSL configuration

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Secure TLS Settings

```typescript
const apiManagementService = new azurenative.apimanagement.ApiManagementService("my-api-mgmt", {
    customProperties: {
        "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls10": "false",  // Disable TLS 1.0
        "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Protocols.Tls11": "false",  // Disable TLS 1.1
        "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls10": "false",  // Disable backend TLS 1.0
        "Microsoft.WindowsAzure.ApiManagement.Gateway.Security.Backend.Protocols.Tls11": "false",  // Disable backend TLS 1.1
    },
    // ... other config
});
```

### app-service-disable-ftp

**Severity:** medium · **Enforcement:** advisory

Require App Service to block insecure FTP access

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Disable FTP Access

```typescript
const webApp = new azurenative.web.WebApp("mywebapp", {
    siteConfig: {
        ftpsState: "Disabled",  // Disable FTP access (or use "FtpsOnly" for encrypted FTP)
    },
    // ... other config
});
```

### app-service-https-only

**Severity:** high · **Enforcement:** advisory

Require App Service to enforce HTTPS only connections

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enforce HTTPS Only

```typescript
const webApp = new azurenative.web.WebApp("mywebapp", {
    httpsOnly: true,  // Redirect all HTTP traffic to HTTPS
    siteConfig: {
        minTlsVersion: "1.2",  // Set minimum TLS version
    },
    // ... other config
});
```

### app-service-managed-updates

**Severity:** medium · **Enforcement:** advisory

Ensure App Service applications have managed updates enabled to maintain current software versions and security patches.

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

Remediation

##### Fix: Enable Managed Updates for App Service

Your App Service needs to be configured for managed updates to ensure security patches are applied automatically. Configure the required settings and tags:

##### Step 1: Enable Always On and Update Settings

```typescript
const webApp = new azure.web.WebApp("myWebApp", {
    resourceGroupName: resourceGroup.name,
    serverFarmId: plan.id,
    siteConfig: {
        alwaysOn: true,  // Keep app loaded for consistent updates
        // Other site config settings
    },
    tags: {
        ManagedUpdates: "enabled",  // Document that managed updates are enabled
    },
});
```

##### Step 2: Configure with Auto-Swap for Staging (Optional but Recommended)

```typescript
const webApp = new azure.web.WebApp("myWebApp", {
    resourceGroupName: resourceGroup.name,
    serverFarmId: plan.id,
    siteConfig: {
        alwaysOn: true,
        autoSwapSlotName: "production",  // Auto-swap from staging after updates
    },
    tags: {
        ManagedUpdates: "enabled",
        UpdateStrategy: "staging-swap",
    },
});

// Create a staging slot for testing updates
const stagingSlot = new azure.web.WebAppSlot("staging", {
    name: webApp.name,
    slot: "staging",
    resourceGroupName: resourceGroup.name,
    siteConfig: {
        alwaysOn: true,
    },
});
```

##### Accepted Tag Values

The `ManagedUpdates` tag must be set to one of: `enabled`, `true`, `yes`, or `1`.

This ensures your App Service automatically receives security patches and platform updates while maintaining availability.

### application-gateway-has-health-probes

**Severity:** medium · **Enforcement:** advisory

Require Application Gateway to enable health probes

- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Configure Health Probes

```typescript
const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
    probes: [{
        name: "health-probe",
        protocol: "Https",
        path: "/health",
        interval: 30,
        timeout: 30,
        unhealthyThreshold: 3,
        match: {
            statusCodes: ["200-399"],
        },
    }],
    backendHttpSettingsCollection: [{
        name: "backend-settings",
        probe: { id: healthProbe.id },  // Associate probe with backend settings
        // ... other config
    }],
    // ... other config
});
```

### application-gateway-https-redirection

**Severity:** high · **Enforcement:** advisory

Ensure Application Gateway enforces HTTPS redirection to protect data in transit.

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure HTTP to HTTPS Redirection

Your Application Gateway has HTTP listeners but doesn't redirect traffic to HTTPS. All HTTP traffic should be automatically redirected to HTTPS for security.

##### Configure HTTP to HTTPS Redirection

```typescript
const appGateway = new azure.network.ApplicationGateway("myGateway", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,

    // ... other configuration ...

    // Define HTTP listener (port 80)
    httpListeners: [
        {
            name: "http-listener",
            protocol: "Http",
            frontendIPConfiguration: { id: frontendIP.id },
            frontendPort: { id: frontendPort80.id },
        },
        {
            name: "https-listener",
            protocol: "Https",
            frontendIPConfiguration: { id: frontendIP.id },
            frontendPort: { id: frontendPort443.id },
            sslCertificate: { id: sslCert.id },
        },
    ],

    // Create redirect configuration
    redirectConfigurations: [{
        name: "http-to-https-redirect",
        redirectType: "Permanent",  // HTTP 301
        targetListener: {
            id: pulumi.interpolate`${appGateway.id}/httpListeners/https-listener`,
        },
        includePath: true,
        includeQueryString: true,
    }],

    // Apply redirect to HTTP listener
    requestRoutingRules: [
        {
            name: "http-redirect-rule",
            ruleType: "Basic",
            priority: 100,
            httpListener: {
                id: pulumi.interpolate`${appGateway.id}/httpListeners/http-listener`,
            },
            redirectConfiguration: {
                id: pulumi.interpolate`${appGateway.id}/redirectConfigurations/http-to-https-redirect`,
            },
        },
        {
            name: "https-rule",
            ruleType: "Basic",
            priority: 110,
            httpListener: {
                id: pulumi.interpolate`${appGateway.id}/httpListeners/https-listener`,
            },
            backendAddressPool: { id: backendPool.id },
            backendHttpSettings: { id: backendSettings.id },
        },
    ],
});
```

**Note**: Using "Permanent" (HTTP 301) redirect type tells browsers to always use HTTPS for future requests, improving security and performance.

### application-gateway-multi-az

**Severity:** medium · **Enforcement:** advisory

Require Application Gateway to be configured across multiple availability zones

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Deploy Across Multiple Availability Zones

```typescript
const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
    zones: ["1", "2", "3"],  // Deploy across at least 2 availability zones
    // ... other config
});
```

### application-gateway-tls

**Severity:** high · **Enforcement:** advisory

Require Application Gateway to have secure TLS configuration

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Secure TLS Policy

```typescript
const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
    sslPolicy: {
        policyType: "Predefined",
        policyName: "AppGwSslPolicy20220101",  // Use modern policy with TLS 1.2+
    },
    // ... other config
});
```

### application-gateway-waf

**Severity:** high · **Enforcement:** advisory

Require Application Gateway to have Web Application Firewall enabled

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Enable Web Application Firewall

```typescript
const appGateway = new azurenative.network.ApplicationGateway("my-app-gateway", {
    sku: {
        name: "WAF_v2",
        tier: "WAF_v2",  // Use WAF-enabled SKU
    },
    webApplicationFirewallConfiguration: {
        enabled: true,  // Enable WAF protection
        firewallMode: "Prevention",  // Block threats
        ruleSetType: "OWASP",
        ruleSetVersion: "3.2",
    },
    // ... other config
});
```

### azure-firewall-threat-intelligence

**Severity:** high · **Enforcement:** advisory

Require Azure Firewall to have threat intelligence enabled

- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Enable Threat Intelligence on Azure Firewall

```typescript
const azureFirewall = new azurenative.network.AzureFirewall("my-firewall", {
    sku: { tier: "Standard" },
    threatIntelMode: "Deny",  // Set to "Deny" to block malicious traffic
    // ... other config
});
```

### backup-instance-configuration

**Severity:** medium · **Enforcement:** advisory

Ensure backup instances are properly configured with backup policies and cross-region replication.

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Configure Backup Instance Properly

Ensure your backup instance has proper configuration:

```typescript
const backupInstance = new azure.dataprotection.BackupInstance("disk-backup", {
    resourceGroupName: resourceGroup.name,
    vaultName: backupVault.name,
    properties: {
        dataSourceInfo: {
            resourceId: disk.id,
            resourceType: "Microsoft.Compute/disks",
        },
        policyInfo: {
            policyId: backupPolicy.id,
        },
    },
});
```

**Note**: Ensure the backup vault has appropriate storage settings and the backup policy defines proper retention.

### blob-service-lifecycle

**Severity:** medium · **Enforcement:** advisory

Require BlobServiceProperties to have versioning, change feed, and retention policies enabled

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Configure Blob Service Lifecycle Policies

```typescript
const blobService = new azurenative.storage.BlobServiceProperties("default", {
    isVersioningEnabled: true,  // Enable versioning
    changeFeed: { enabled: true },  // Enable change feed
    deleteRetentionPolicy: { enabled: true, days: 7 },  // Enable delete retention
    // ... other config
});
```

### cdn-distribution-logging-enabled

**Severity:** medium · **Enforcement:** advisory

Collect audit logs from CDN distributions for security monitoring.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable CDN Distribution Logging

Your CDN needs audit logging configured. Enable diagnostic settings to collect access logs:

```typescript
const cdnProfile = new azure.cdn.Profile("myCdnProfile", {
    // ... other properties
    tags: {
        "LoggingEnabled": "enabled",
        "CDNLogging": "true",
    },
});

// Configure diagnostic settings for the CDN profile
const cdnDiagnostics = new azure.insights.DiagnosticSetting("cdnDiagnostics", {
    name: "cdn-logging",
    resourceUri: cdnProfile.id,
    workspaceId: logAnalyticsWorkspace.id,  // Send logs to Log Analytics
    logs: [
        {
            category: "AzureCdnAccessLog",  // Access logs for standard CDN
            enabled: true,
            retentionPolicy: { enabled: true, days: 90 },
        },
    ],
});
```

For Azure Front Door (modern CDN):

```typescript
logs: [
    {
        category: "FrontDoorAccessLog",  // Access logs
        enabled: true,
    },
    {
        category: "FrontDoorHealthProbeLog",  // Health probe logs
        enabled: true,
    },
],
```

### container-instance-privileged-mode

**Severity:** high · **Enforcement:** advisory

Ensure Container Instances user for privileged mode check.

- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.
- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Disable Privileged Mode for Container Instances

Your container is configured to run in privileged mode. Remove privileged access and use proper security context:

```typescript
const containerGroup = new azure.containerinstance.ContainerGroup("myContainerGroup", {
    containers: [{
        name: "myContainer",
        image: "nginx:latest",
        resources: {
            requests: { cpu: 1, memoryInGB: 1.5 },
            limits: { cpu: 2, memoryInGB: 3 },  // Add resource limits
        },
        securityContext: {
            privileged: false,  // Never set to true
            runAsUser: 1000,  // Non-root user
            runAsGroup: 1000,  // Non-root group
            readOnlyRootFilesystem: true,  // Make root filesystem read-only
            capabilities: {
                drop: ["ALL"],  // Drop all capabilities
                // Only add specific needed capabilities
            },
        },
    }],
    osType: "Linux",
    ipAddress: { type: "Private" },  // Use private networking
});
```

**Critical**: Never set `privileged: true` or add dangerous capabilities like SYS_ADMIN, NET_ADMIN, or SYS_PTRACE.

### container-registry-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Container Registry to use customer-managed keys

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Container Registry Customer-Managed Keys

```typescript
const registry = new azurenative.containerregistry.Registry("my-registry", {
    sku: { name: "Premium" },  // Premium SKU required for customer-managed keys
    encryption: {
        status: "enabled",
        keyVaultProperties: {
            keyIdentifier: key.keyUri,  // Key Vault key URI
            identity: registryIdentity.id,  // User-assigned identity with Key Vault access
        },
    },
    // ... other config
});
```

### cosmos-db-autoscaling-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Cosmos DB autoscaling is enabled.

- **A.8.6 Capacity management** — The use of resources shall be monitored and adjusted in line with current and expected capacity requirements.

Remediation

##### Fix: Enable Autoscaling for Cosmos DB

Your Cosmos DB account needs autoscaling configured for optimal performance and cost management:

```typescript
const cosmosAccount = new azure.documentdb.DatabaseAccount("myCosmosDb", {
    // ... other properties
});

// For individual containers, enable autoscale throughput
const container = new azure.documentdb.SqlResourceSqlContainer("myContainer", {
    // ... other properties
    options: {
        autoscaleSettings: {
            maxThroughput: 4000,  // Maximum RU/s - scales from 10% (400) to this value
        },
    },
});
```

Autoscaling helps manage costs by automatically adjusting throughput based on actual usage.

### cosmos-db-backup-policies

**Severity:** medium · **Enforcement:** advisory

Require Cosmos DB account to have backup policies configured

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Configure Cosmos DB Backup Policies

```typescript
// Option 1: Continuous Backup (recommended)
const cosmosDbContinuous = new azurenative.cosmosdb.DatabaseAccount("my-cosmosdb", {
    databaseAccountOfferType: "Standard",
    backupPolicy: {
        type: "Continuous",  // Enable continuous backup
        continuousModeProperties: {
            tier: "Continuous30Days",  // 30-day point-in-time restore
        },
    },
    // ... other config
});

// Option 2: Periodic Backup
const cosmosDbPeriodic = new azurenative.cosmosdb.DatabaseAccount("my-cosmosdb", {
    databaseAccountOfferType: "Standard",
    backupPolicy: {
        type: "Periodic",  // Enable periodic backup
        periodicModeProperties: {
            backupIntervalInMinutes: 240,  // 4 hours
            backupRetentionIntervalInHours: 720,  // 30 days
        },
    },
    // ... other config
});
```

### cosmos-db-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Cosmos DB to use customer-managed keys

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Keys for Cosmos DB

```typescript
const cosmosAccount = new azurenative.cosmosdb.DatabaseAccount("my-cosmos-account", {
    databaseAccountOfferType: "Standard",
    keyVaultKeyUri: key.keyUriWithVersion,  // Reference Key Vault key for encryption
    identity: {
        type: "UserAssigned",  // Use managed identity
        userAssignedIdentities: { [identity.id]: {} },
    },
    defaultIdentity: pulumi.interpolate`UserAssignedIdentity=${identity.id}`,
    // ... other config
});
```

### cosmos-db-pitr-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Cosmos DB point-in-time recovery is enabled for data protection.

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Enable Point-in-Time Recovery for Cosmos DB

Your Cosmos DB account needs continuous backup for point-in-time recovery:

```typescript
const cosmosAccount = new azure.documentdb.DatabaseAccount("myCosmosDb", {
    // ... other properties
    backupPolicy: {
        type: "Continuous",  // Enable continuous backup for PITR
        continuousModeProperties: {
            tier: "Continuous7Days",  // or "Continuous30Days"
        },
    },
});
```

**Note**: Continuous backup allows restore to any point within the retention period (7 or 30 days).

### cosmos-db-private-endpoints

**Severity:** high · **Enforcement:** advisory

Require Cosmos DB account to have public network access disabled (indicating private endpoint usage)

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Configure Cosmos DB with Private Endpoints

```typescript
const cosmosAccount = new azurenative.cosmosdb.DatabaseAccount("my-cosmos-account", {
    databaseAccountOfferType: "Standard",
    publicNetworkAccess: "Disabled",  // Disable public access to enforce private endpoints
    // ... other config
});
```

### custom-image-validation

**Severity:** medium · **Enforcement:** advisory

Validate custom managed images meet governance and security requirements

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Add Required Governance Tags

```typescript
const customImage = new azurenative.compute.Image("my-custom-image", {
    tags: {
        "approved-by": "security-team@example.com",
        "creation-date": "2025-01-07",  // YYYY-MM-DD format
        "source-image": "Canonical:UbuntuServer:20.04-LTS",
        "vulnerability-scan-passed": "true",  // Must be 'true', 'yes', or 'passed'
        "hardening-applied": "true",  // Must be 'true', 'yes', or 'applied'
    },
    // ... other config
});
```

### data-factory-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Data Factory to use customer-managed keys for encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Keys for Data Factory

```typescript
const factory = new azurenative.datafactory.Factory("my-data-factory", {
    encryption: {
        keyName: key.name,  // Reference Key Vault key
        vaultBaseUrl: pulumi.interpolate`https://${keyVault.name}.vault.azure.net/`,
        keyVersion: key.version,  // Optional: specify key version
    },
    // ... other config
});
```

### defender-for-cloud-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Microsoft Defender for Cloud is enabled for asset discovery and threat detection.

- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable Microsoft Defender for Cloud

Your resources need Microsoft Defender for Cloud enabled for threat detection:

```typescript
// Enable Advanced Threat Protection for a resource
const atp = new azure.security.AdvancedThreatProtection("myResourceATP", {
    resourceId: storageAccount.id,  // or other resource
    isEnabled: true,  // Enable threat detection
});

// Tag your resource to indicate Defender is enabled
tags: {
    "DefenderForCloud": "enabled",
    "AdvancedThreatProtection": "true",
    "SecurityMonitoring": "configured",
}
```

Enable Defender for specific resource types: Storage, SQL, Key Vault, Kubernetes, App Service, etc.

### diagnostic-setting-configuration

**Severity:** medium · **Enforcement:** advisory

Ensure diagnostic settings are properly configured with required destinations, log categories, and retention policies.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Configure Diagnostic Settings Properly

Ensure your diagnostic settings include required destinations, log categories, and retention:

```typescript
const diagnostics = new azure.monitor.DiagnosticSetting("myDiagnostics", {
    resourceUri: resource.id,
    workspaceId: logAnalyticsWorkspace.id,  // Log Analytics
    storageAccountId: storageAccount.id,     // Storage for retention
    logs: [
        {
            category: "AuditLogs",
            enabled: true,
            retentionPolicy: { enabled: true, days: 365 },
        },
    ],
    metrics: [
        {
            category: "AllMetrics",
            enabled: true,
        },
    ],
});
```

**Note**: Configure appropriate log categories based on the resource type being monitored.

### dms-instance-public-access

**Severity:** high · **Enforcement:** advisory

Prevent public accessibility of Database Migration Service instances.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.

Remediation

##### Fix: Disable Public Access for Database Migration Service

Your Database Migration Service allows public network access. Disable it and use VNet integration:

```typescript
const dmsService = new azure.datamigration.Service("myDMS", {
    // ... other properties
    publicNetworkAccess: "Disabled",  // Block public access
    virtualSubnetId: privateSubnet.id,  // Deploy in private subnet
    tags: {
        "PrivateEndpoint": "configured",
        "NetworkSecurityGroup": "associated",
    },
});
```

This ensures the DMS instance is only accessible from within your virtual network.

### event-hubs-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Event Hub namespace to use customer-managed keys for encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Keys for Event Hub Namespace

```typescript
const namespace = new azurenative.eventhub.Namespace("my-eventhub-namespace", {
    sku: {
        tier: "Premium",  // Customer-managed keys require Premium or Dedicated tier
    },
    encryption: {
        keySource: "Microsoft.KeyVault",  // Use Key Vault for customer-managed keys
        keyVaultProperties: [{
            keyName: "eventhub-encryption-key",
            keyVaultUri: keyVault.properties.vaultUri,
            identity: {
                userAssignedIdentity: identity.id,
            },
        }],
    },
    // ... other config
});
```

### event-hubs-retention

**Severity:** medium · **Enforcement:** advisory

Require Event Hubs to have proper retention policies configured

- **A.5.33 Protection of records** — Records shall be protected from loss, destruction, falsification, unauthorized access and unauthorized release.

Remediation

##### Fix: Configure Proper Event Hub Retention Policies

```typescript
const eventHub = new azurenative.eventhub.EventHub("my-eventhub", {
    namespaceName: namespace.name,
    messageRetentionInDays: 7,  // Set retention period (1-7 days for Standard, up to 90 days for Premium)
    // ... other config
});
```

### flow-log-configuration

**Severity:** medium · **Enforcement:** advisory

Require proper Flow Log configuration for network monitoring

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Configure Flow Log Settings

```typescript
const flowLog = new azurenative.network.FlowLog("my-flowlog", {
    retentionPolicy: {
        enabled: true,
        days: 90,  // Set retention period (minimum 30 days)
    },
    format: {
        version: 2,  // Use version 2 for enhanced data
    },
    // ... other config
});
```

### front-door-tls

**Severity:** high · **Enforcement:** advisory

Require Front Door custom domains to use secure TLS configuration

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Secure TLS Settings

```typescript
const customDomain = new azurenative.cdn.AFDCustomDomain("my-custom-domain", {
    tlsSettings: {
        minimumTlsVersion: "TLS12",  // Enforce minimum TLS 1.2
        certificateType: "ManagedCertificate",  // Use Azure-managed certificates
    },
    // ... other config
});
```

### function-app-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Function Apps to use customer-managed keys

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Key Vault Reference Identity

```typescript
const functionApp = new azurenative.web.WebApp("myfunctionapp", {
    kind: "functionapp",
    identity: {
        type: "UserAssigned",  // Or "SystemAssigned"
        userAssignedIdentities: {
            [managedIdentity.id]: {},
        },
    },
    keyVaultReferenceIdentity: managedIdentity.id,  // Enable Key Vault integration
    // ... other config
});
```

### function-public-access

**Severity:** high · **Enforcement:** advisory

Ensure Azure Functions restrict public access.

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Restrict Public Access to Function App

Your Function App allows unrestricted public access. Configure IP restrictions to limit access to specific IP ranges:

##### Option 1: Configure IP Security Restrictions

```typescript
const functionApp = new azure.web.WebApp("myFunction", {
    kind: "functionapp",
    resourceGroupName: resourceGroup.name,
    serverFarmId: plan.id,
    siteConfig: {
        ipSecurityRestrictions: [
            {
                ipAddress: "203.0.113.0/24",  // Your allowed IP range
                action: "Allow",
                priority: 100,
                name: "AllowOfficeNetwork",
            },
            {
                ipAddress: "198.51.100.10/32",  // Specific VPN IP
                action: "Allow",
                priority: 110,
                name: "AllowVPN",
            },
        ],
        scmIpSecurityRestrictions: [  // Also restrict deployment access
            {
                ipAddress: "203.0.113.0/24",
                action: "Allow",
                priority: 100,
                name: "AllowOfficeDeployments",
            },
        ],
    },
    httpsOnly: true,  // Enforce HTTPS
});
```

##### Option 2: Disable Public Network Access (use with VNet integration)

```typescript
const functionApp = new azure.web.WebApp("myFunction", {
    kind: "functionapp",
    resourceGroupName: resourceGroup.name,
    serverFarmId: plan.id,
    publicNetworkAccess: "Disabled",  // Block all public access
    virtualNetworkSubnetId: subnet.id,  // Require VNet integration
    httpsOnly: true,
});
```

**Do not use**: `ipAddress: "0.0.0.0/0"` or leaving `ipSecurityRestrictions` empty, as these allow unrestricted public access.

### function-vnet-integration

**Severity:** medium · **Enforcement:** advisory

Ensure Azure Functions are integrated with Virtual Networks.

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.

Remediation

##### Fix: Enable VNet Integration for Function App

Your Function App is not integrated with a Virtual Network. Configure VNet integration to isolate your function from the public internet:

##### Step 1: Create a Dedicated Subnet for Function App

```typescript
const functionSubnet = new azure.network.Subnet("functionSubnet", {
    virtualNetworkName: vnet.name,
    resourceGroupName: resourceGroup.name,
    addressPrefix: "10.0.2.0/24",
    delegations: [{
        name: "delegation",
        serviceName: "Microsoft.Web/serverFarms",  // Required for Function Apps
    }],
});
```

##### Step 2: Configure Function App with VNet Integration

```typescript
const functionApp = new azure.web.WebApp("myFunction", {
    kind: "functionapp",
    resourceGroupName: resourceGroup.name,
    serverFarmId: plan.id,  // Must be Premium or Dedicated plan for VNet
    virtualNetworkSubnetId: functionSubnet.id,  // Connect to VNet subnet
    siteConfig: {
        vnetRouteAllEnabled: true,  // Route ALL outbound traffic through VNet
    },
});
```

##### Complete Example with Private Subnet

```typescript
const functionApp = new azure.web.WebApp("myFunction", {
    kind: "functionapp",
    resourceGroupName: resourceGroup.name,
    serverFarmId: premiumPlan.id,
    virtualNetworkSubnetId: functionSubnet.id,
    siteConfig: {
        vnetRouteAllEnabled: true,
        ipSecurityRestrictions: [],  // No public inbound access
    },
    publicNetworkAccess: "Disabled",  // Completely disable public access
});
```

**Note**: VNet integration requires an App Service Plan (Premium V2 or higher) or Elastic Premium plan. Consumption plans do not support VNet integration.

### hdinsight-cluster-public-access

**Severity:** high · **Enforcement:** advisory

Ensure HDInsight clusters restrict public access to master nodes.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Disable Public Access for HDInsight Cluster

Your HDInsight cluster allows public access. Configure private link for secure connectivity:

```typescript
const hdinsightCluster = new azure.hdinsight.Cluster("myHDInsight", {
    // ... other properties
    computeProfile: {
        roles: [{
            name: "headnode",
            targetInstanceCount: 2,
            hardwareProfile: { vmSize: "Standard_D3_v2" },
            virtualNetworkProfile: {
                id: vnet.id,
                subnet: privateSubnet.id,
            },
        }],
    },
    networkProperties: {
        resourceProviderConnection: "Inbound",  // Disable outbound public access
        privateLink: "Enabled",  // Enable private link
    },
    tags: {
        "PublicAccess": "disabled",
        "PrivateLink": "enabled",
    },
});
```

### hdinsight-kerberos-enabled

**Severity:** high · **Enforcement:** advisory

Ensure HDInsight Kerberos is enabled.

- **A.5.16 Identity management** — The full life cycle of identities shall be managed.
- **A.8.5 Secure authentication** — Secure authentication technologies and procedures shall be implemented based on information access restrictions and the topic-specific policy on access control.

Remediation

##### Fix: Enable Kerberos Authentication for HDInsight

Your HDInsight cluster needs Kerberos authentication for secure access:

```typescript
const hdinsightCluster = new azure.hdinsight.Cluster("myHDInsight", {
    // ... other properties
    securityProfile: {
        directoryType: "ActiveDirectory",  // Use Azure AD Domain Services
        domain: "yourdomain.com",
        domainUsername: "admin@yourdomain.com",
        domainUserPassword: domainPassword,
        ldapsUrls: ["ldaps://yourdomain.com:636"],
        clusterUsersGroupDNs: ["CN=HadoopUsers,OU=Groups,DC=yourdomain,DC=com"],
    },
    tags: {
        "KerberosEnabled": "true",
        "EnterpriseSecurityPackage": "enabled",
    },
});
```

**Requirements**: Azure AD Domain Services must be configured before enabling Kerberos.

### key-vault-access-policies

**Severity:** high · **Enforcement:** advisory

Require proper access controls for Key Vault access policies

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Use Specific Permissions Instead of "all"

```typescript
const keyVault = new azurenative.keyvault.Vault("my-keyvault", {
    properties: {
        sku: { name: "standard" },
        accessPolicies: [{
            tenantId: tenantId,
            objectId: servicePrincipalId,
            permissions: {
                keys: ["get", "list", "encrypt", "decrypt"],  // Specific permissions instead of "all"
                secrets: ["get", "list"],  // Specific permissions instead of "all"
            },
        }],
    },
    // ... other config
});
```

### key-vault-key-configuration

**Severity:** high · **Enforcement:** advisory

Require proper Key Vault key creation and configuration

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Key with Proper Type, Size, and Operations

```typescript
const key = new azurenative.keyvault.Key("my-key", {
    properties: {
        kty: "RSA",  // or "RSA-HSM" for hardware protection
        keySize: 2048,  // Minimum 2048 bits for RSA
        keyOps: ["encrypt", "decrypt"],  // Specify exact operations needed
        attributes: {
            exportable: false,
        },
    },
    // ... other config
});
```

### key-vault-key-lifecycle

**Severity:** high · **Enforcement:** advisory

Require proper Key Vault key deletion and lifecycle management

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Key Vault Key Lifecycle Attributes

```typescript
const key = new azurenative.keyvault.Key("my-key", {
    properties: {
        kty: "RSA",
        attributes: {
            exp: 1735689600,  // Set expiration date (Unix epoch timestamp)
            nbf: 1704067200,  // Set not-before date (Unix epoch timestamp)
        },
        // ... other config
    },
});
```

### key-vault-key-not-scheduled-for-deletion

**Severity:** high · **Enforcement:** advisory

Ensure Key Vault keys are not scheduled for deletion and have proper lifecycle management.

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Protect Keys from Deletion in Key Vault

Your Key Vault keys lack deletion protection. Enable soft delete and purge protection:

```typescript
const keyVault = new azure.keyvault.Vault("myVault", {
    // ... other properties
    properties: {
        enableSoftDelete: true,  // Enable soft delete (mandatory)
        softDeleteRetentionInDays: 90,  // Retain deleted items for 90 days
        enablePurgeProtection: true,  // Prevent permanent deletion during retention
        sku: { family: "A", name: "standard" },
    },
});
```

**Important**: Once enabled, purge protection cannot be disabled. Ensure this is intended for production vaults.

### key-vault-key-rotation

**Severity:** high · **Enforcement:** advisory

Require Key Vault keys to have rotation policies configured

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Key Vault Key Rotation Policy

```typescript
const key = new azurenative.keyvault.Key("my-key", {
    properties: {
        kty: "RSA",
        rotationPolicy: {
            attributes: {
                expiryTime: "P2Y",  // Set expiry time for key versions
            },
            lifetimeActions: [{
                action: { type: "rotate" },
                trigger: { timeAfterCreate: "P90D" },  // Rotate 90 days after creation
            }],
        },
        // ... other config
    },
});
```

### key-vault-network-access

**Severity:** high · **Enforcement:** advisory

Require Key Vault to have network access controls configured

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Configure Key Vault Network Access Controls

```typescript
const vault = new azurenative.keyvault.Vault("my-key-vault", {
    properties: {
        sku: { name: "standard" },
        networkAcls: {
            defaultAction: "Deny",  // Set default action to Deny
            bypass: "AzureServices",
            // ... other config
        },
        // ... other config
    },
});
```

### key-vault-purge-protection

**Severity:** high · **Enforcement:** advisory

Require Key Vault to have purge protection enabled

- **A.5.33 Protection of records** — Records shall be protected from loss, destruction, falsification, unauthorized access and unauthorized release.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Key Vault Purge Protection

```typescript
const vault = new azurenative.keyvault.Vault("my-key-vault", {
    properties: {
        sku: { name: "standard" },
        enablePurgeProtection: true,  // Enable purge protection
        // ... other config
    },
});
```

### key-vault-soft-delete

**Severity:** high · **Enforcement:** advisory

Require Key Vault to have soft delete enabled with appropriate retention

- **A.5.33 Protection of records** — Records shall be protected from loss, destruction, falsification, unauthorized access and unauthorized release.
- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Enable Key Vault Soft Delete

```typescript
const vault = new azurenative.keyvault.Vault("my-key-vault", {
    properties: {
        sku: { name: "standard" },
        enableSoftDelete: true,  // Enable soft delete
        softDeleteRetentionInDays: 90,  // Set retention period (minimum 90 days)
        // ... other config
    },
});
```

### keyvault-rbac-least-privilege

**Severity:** high · **Enforcement:** advisory

Ensure Key Vaults using RBAC use appropriate Key Vault-specific roles instead of broad management roles

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Enable RBAC Authorization on Key Vault

```typescript
const keyVault = new azurenative.keyvault.Vault("my-keyvault", {
    properties: {
        sku: { name: "standard" },
        enableRbacAuthorization: true,  // Enable RBAC for better access control
        accessPolicies: [],
    },
    // ... other config
});
```

### load-balancer-cross-zone-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Load Balancer cross-zone load balancing is enabled.

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Enable Cross-Zone Load Balancing

Your Load Balancer needs to be configured for cross-zone load balancing to ensure high availability across availability zones.

##### Configure Zone-Redundant Load Balancer

```typescript
// Create zone-redundant public IP
const publicIP = new azure.network.PublicIPAddress("myPublicIP", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    publicIPAllocationMethod: "Static",
    sku: {
        name: "Standard",  // Standard SKU required for zone redundancy
        tier: "Regional",
    },
    zones: ["1", "2", "3"],  // Deploy across all availability zones
});

// Create zone-redundant load balancer
const loadBalancer = new azure.network.LoadBalancer("myLB", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,

    sku: {
        name: "Standard",  // Standard SKU supports cross-zone balancing
        tier: "Regional",
    },

    frontendIPConfigurations: [{
        name: "frontend",
        publicIPAddress: { id: publicIP.id },
        zones: ["1", "2", "3"],  // Zone-redundant configuration
    }],

    // ... backend pools, rules, probes ...
});
```

##### Deploy Backend Resources Across Zones

Ensure your backend resources (VMs, VMSS) are distributed across zones:

```typescript
const vmss = new azure.compute.VirtualMachineScaleSet("backend-vmss", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,

    sku: {
        name: "Standard_D2s_v3",
        capacity: 3,
    },

    zones: ["1", "2", "3"],  // Distribute instances across zones

    // ... other VMSS configuration ...
});
```

##### Optimize Health Probes for Fast Failover

```typescript
const loadBalancer = new azure.network.LoadBalancer("myLB", {
    // ... other configuration ...

    probes: [{
        name: "health-probe",
        protocol: "Http",  // Note: Azure Load Balancer probes don't support HTTPS protocol
        port: 443,         // The probe connects to HTTPS port, but protocol detection is TCP/HTTP only
        requestPath: "/health",
        intervalInSeconds: 5,  // Fast probe interval
        numberOfProbes: 2,     // Quick failover (5s * 2 = 10s total)
    }],
});
```

**Note**: Standard SKU Load Balancers are zone-redundant by default when the frontend IP is zone-redundant. Basic SKU does not support availability zones - upgrade to Standard.

### load-balancer-deletion-protection

**Severity:** high · **Enforcement:** advisory

Ensure critical Load Balancers have resource locks to prevent accidental deletion.

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Apply Resource Lock to Load Balancer

Your Load Balancer needs deletion protection. Apply a resource lock to prevent accidental deletion:

```typescript
const lock = new azure.authorization.ManagementLockAtResourceLevel("lb-delete-lock", {
    level: "CanNotDelete",
    lockName: "lb-delete-lock",
    notes: "Prevents accidental deletion of production load balancer",
    resourceGroupName: resourceGroup.name,
    resourceName: loadBalancer.name,
    resourceProviderNamespace: "Microsoft.Network",
    resourceType: "loadBalancers",
});
```

##### Lock Levels
- **CanNotDelete**: Users can read and modify the resource, but cannot delete it
- **ReadOnly**: Users can read the resource, but cannot modify or delete it

### load-balancer-health-probes

**Severity:** medium · **Enforcement:** advisory

Require Load Balancer to enable health probes

- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Configure Load Balancer Health Probes

```typescript
const loadBalancer = new azurenative.network.LoadBalancer("my-load-balancer", {
    sku: { name: "Standard" },
    probes: [{
        name: "http-health-probe",
        properties: {
            protocol: "Http",
            port: 80,
            requestPath: "/health",  // Configure health check endpoint
        },
    }],
    loadBalancingRules: [{
        name: "http-rule",
        properties: {
            probe: { id: probeId },  // Associate probe with rule
            // ... other config
        },
    }],
});
```

### load-balancer-https-listeners

**Severity:** high · **Enforcement:** advisory

Ensure Load Balancer uses TLS/HTTPS listeners only for secure communication.

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Use HTTPS Listeners Instead of HTTP

Your Load Balancer has HTTP listeners without HTTPS alternatives. All traffic should be encrypted in transit using HTTPS.

##### Replace HTTP Listeners with HTTPS

```typescript
const loadBalancer = new azure.network.LoadBalancer("myLB", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: { name: "Standard" },

    frontendIPConfigurations: [{
        name: "frontend",
        publicIPAddress: { id: publicIP.id },
    }],

    loadBalancingRules: [
        // Remove HTTP rule (port 80)
        // {
        //     name: "http-rule",
        //     frontendPort: 80,
        //     backendPort: 80,
        //     protocol: "Tcp",
        // },

        // Add HTTPS rule (port 443)
        {
            name: "https-rule",
            frontendPort: 443,
            backendPort: 443,
            protocol: "Tcp",
            frontendIPConfiguration: {
                id: pulumi.interpolate`${loadBalancer.id}/frontendIPConfigurations/frontend`,
            },
            backendAddressPool: {
                id: pulumi.interpolate`${loadBalancer.id}/backendAddressPools/backend`,
            },
            probe: {
                id: pulumi.interpolate`${loadBalancer.id}/probes/https-probe`,
            },
        },
    ],

    probes: [{
        name: "https-probe",
        protocol: "Http",  // Note: Azure Load Balancer probes don't support HTTPS protocol
        port: 443,         // The probe connects to HTTPS port, but protocol detection is TCP/HTTP only
        requestPath: "/health",
        intervalInSeconds: 15,
        numberOfProbes: 2,
    }],
});
```

**Note**: For Azure Application Gateway (Layer 7), you can also implement HTTP to HTTPS redirection. For Azure Load Balancer (Layer 4), you should only expose HTTPS ports.

### load-balancer-logging

**Severity:** medium · **Enforcement:** advisory

Ensure Load Balancer has logging enabled for comprehensive security and performance analysis.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable Diagnostic Logging for Load Balancer

Your Load Balancer doesn't have diagnostic settings configured. Enable logging to monitor load balancer health, performance, and security events.

##### Configure Diagnostic Settings

```typescript
const logAnalyticsWorkspace = new azure.operationalinsights.Workspace("logs", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: { name: "PerGB2018" },
});

const loadBalancer = new azure.network.LoadBalancer("myLB", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    // ... other load balancer configuration
});

const diagnosticSetting = new azure.monitor.DiagnosticSetting("lb-diagnostics", {
    resourceUri: loadBalancer.id,
    workspaceId: logAnalyticsWorkspace.id,

    logs: [
        {
            category: "LoadBalancerAlertEvent",
            enabled: true,
            retentionPolicy: {
                enabled: true,
                days: 365,
            },
        },
        {
            category: "LoadBalancerProbeHealthStatus",
            enabled: true,
            retentionPolicy: {
                enabled: true,
                days: 365,
            },
        },
    ],

    metrics: [{
        category: "AllMetrics",
        enabled: true,
        retentionPolicy: {
            enabled: true,
            days: 365,
        },
    }],
});
```

##### Send Logs to Multiple Destinations

For comprehensive monitoring, send logs to multiple destinations:

```typescript
const diagnosticSetting = new azure.monitor.DiagnosticSetting("lb-diagnostics", {
    resourceUri: loadBalancer.id,
    workspaceId: logAnalyticsWorkspace.id,
    storageAccountId: storageAccount.id,  // Long-term storage
    eventHubAuthorizationRuleId: eventHubRule.id,  // Real-time processing

    logs: [
        { category: "LoadBalancerAlertEvent", enabled: true },
        { category: "LoadBalancerProbeHealthStatus", enabled: true },
    ],
    metrics: [{ category: "AllMetrics", enabled: true }],
});
```

**Note**: Standard Load Balancers support diagnostic logging. Basic SKU load balancers have limited logging capabilities - consider upgrading to Standard.

### load-balancer-multi-az

**Severity:** medium · **Enforcement:** advisory

Require Load Balancer to be configured across multiple availability zones

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Configure Load Balancer for Multiple Availability Zones

```typescript
const loadBalancer = new azurenative.network.LoadBalancer("my-lb", {
    sku: {
        name: "Standard",  // Standard SKU required for zone redundancy
    },
    frontendIPConfigurations: [{
        zones: ["1", "2", "3"],  // Deploy across multiple zones
        // ... other config
    }],
});
```

### log-analytics-retention

**Severity:** medium · **Enforcement:** advisory

Require Log Analytics workspace to have appropriate retention policies

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Configure Log Analytics Workspace Retention Policy

```typescript
const workspace = new azurenative.operationalinsights.Workspace("my-workspace", {
    sku: {
        name: "PerGB2018",
    },
    retentionInDays: 90,  // Set to meet compliance requirements (minimum 90 days)
    // ... other config
});
```

### managed-disk-attached-encryption-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Managed Disks are encrypted when attached to virtual machines.

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Encryption for Attached Managed Disk

Your attached managed disk lacks encryption configuration. Enable encryption using one of these methods:

1. Enable platform-managed key encryption (basic):

```typescript
const disk = new azure.compute.Disk("my-disk", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Empty",
    },
    diskSizeGB: 128,
    encryption: {
        type: "EncryptionAtRestWithPlatformKey",
    },
});
```

2. Enable customer-managed key encryption (recommended for sensitive data):

```typescript
// First, create a disk encryption set
const diskEncryptionSet = new azure.compute.DiskEncryptionSet("my-des", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    identity: {
        type: "SystemAssigned",
    },
    encryptionType: "EncryptionAtRestWithCustomerKey",
    activeKey: {
        sourceVault: {
            id: keyVault.id,
        },
        keyUrl: key.keyUriWithVersion,
    },
});

// Then, use it with your disk
const disk = new azure.compute.Disk("my-disk", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Empty",
    },
    diskSizeGB: 128,
    encryption: {
        type: "EncryptionAtRestWithCustomerKey",
        diskEncryptionSetId: diskEncryptionSet.id,
    },
});
```

3. Enable double encryption with platform and customer keys (maximum security):

```typescript
const disk = new azure.compute.Disk("my-disk", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Empty",
    },
    diskSizeGB: 128,
    encryption: {
        type: "EncryptionAtRestWithPlatformAndCustomerKeys",
        diskEncryptionSetId: diskEncryptionSet.id,
    },
});
```

### managed-disk-backup-protection-exists

**Severity:** medium · **Enforcement:** advisory

Ensure Managed Disks have backup protection (existence check).

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Configure Backup Protection for Managed Disks

Your managed disk lacks proper backup configuration. Enable automated backups using Azure Backup or snapshot policies.

**Note**: This policy checks that backup protection exists. Use the 'backup-instance-configuration' and 'snapshot-configuration' resource policies to validate backup configuration details.

##### Option 1: Use Azure Backup with Backup Vault

```typescript
const backupVault = new azure.dataprotection.BackupVault("backup-vault", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    properties: {
        storageSettings: [{
            datastoreType: "VaultStore",
            type: "LocallyRedundant",
        }],
    },
});

const backupPolicy = new azure.dataprotection.BackupPolicy("disk-backup-policy", {
    resourceGroupName: resourceGroup.name,
    vaultName: backupVault.name,
    properties: {
        policyRules: [
            // Configure backup schedule and retention
        ],
    },
});

// Associate disk with backup instance
const backupInstance = new azure.dataprotection.BackupInstance("disk-backup", {
    resourceGroupName: resourceGroup.name,
    vaultName: backupVault.name,
    properties: {
        dataSourceInfo: {
            resourceId: disk.id,
        },
        policyInfo: {
            policyId: backupPolicy.id,
        },
    },
});
```

##### Option 2: Create Manual Snapshots

```typescript
const snapshot = new azure.compute.Snapshot("disk-snapshot", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Copy",
        sourceResourceId: disk.id,
    },
});
```

### managed-disk-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require managed disks to use customer-managed encryption keys

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Keys for Managed Disk

```typescript
const disk = new azurenative.compute.Disk("my-disk", {
    sku: { name: "Premium_LRS" },
    diskSizeGB: 128,
    creationData: { createOption: "Empty" },
    encryption: {
        type: "EncryptionAtRestWithCustomerKey",  // Use customer-managed key
        diskEncryptionSetId: diskEncryptionSet.id,  // Reference to Disk Encryption Set
    },
    // ... other config
});
```

### managed-disk-snapshot-restrict-network-access

**Severity:** high · **Enforcement:** advisory

Ensure Managed Disk snapshots use restrictive network access policies (not AllowAll).

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

Remediation

##### Fix: Use Restrictive Network Access Policy on Managed Disk Snapshot

Your snapshot has network access policy set to 'AllowAll'. Use a more restrictive policy to limit access:

For private endpoint access:

```typescript
const diskAccess = new azure.compute.DiskAccess("my-disk-access", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
});

const snapshot = new azure.compute.Snapshot("my-snapshot", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Copy",
        sourceResourceId: disk.id,
    },
    networkAccessPolicy: "AllowPrivate",
    diskAccessId: diskAccess.id,
});
```

For maximum security, deny all network access:

```typescript
const snapshot = new azure.compute.Snapshot("my-snapshot", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Copy",
        sourceResourceId: disk.id,
    },
    networkAccessPolicy: "DenyAll",
});
```

### managed-disk-snapshot-restrict-public-access

**Severity:** high · **Enforcement:** advisory

Ensure Managed Disk snapshots do not allow public network access.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

Remediation

##### Fix: Disable Public Network Access on Managed Disk Snapshot

Your snapshot allows public network access. Disable public access to prevent unauthorized restore operations:

```typescript
const snapshot = new azure.compute.Snapshot("my-snapshot", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Copy",
        sourceResourceId: disk.id,
    },
    publicNetworkAccess: "Disabled",
    networkAccessPolicy: "AllowPrivate",
});
```

For maximum security, deny all network access:

```typescript
const snapshot = new azure.compute.Snapshot("my-snapshot", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Copy",
        sourceResourceId: disk.id,
    },
    publicNetworkAccess: "Disabled",
    networkAccessPolicy: "DenyAll",
});
```

### managed-disk-unused

**Severity:** medium · **Enforcement:** advisory

Ensure Managed Disks are not unused to maintain proper asset inventory.

- **A.5.9 Inventory of information and other associated assets** — An inventory of information and other associated assets, including owners, shall be developed and maintained.

Remediation

##### Fix: Attach or Delete Unused Managed Disk

Your managed disk is not attached to any VM. Take one of these actions:

1. Attach the disk to a VM as a data disk:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    storageProfile: {
        dataDisks: [{
            lun: 0,
            createOption: "Attach",
            managedDisk: {
                id: disk.id,
            },
        }],
    },
});
```

2. If the disk is truly unused, delete it to reduce costs and maintain clean asset inventory.

### ml-compute-instance-cmk-configured

**Severity:** high · **Enforcement:** advisory

Ensure Machine Learning compute instances use customer-managed keys for disk encryption.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Enable Customer-Managed Keys for ML Compute Instance

Your ML compute instance needs disk encryption with customer-managed keys:

```typescript
// First configure the ML Workspace with CMK
const mlWorkspace = new azure.machinelearningservices.Workspace("myWorkspace", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
    encryption: {
        status: "Enabled",
        keyVaultProperties: {
            keyIdentifier: encryptionKey.id,
            keyVaultArmId: keyVault.id,
        },
    },
    sku: { name: "Basic" },
});

// Compute instance inherits encryption from workspace
const mlCompute = new azure.machinelearningservices.Compute("myMLCompute", {
    workspaceName: mlWorkspace.name,
    computeType: "ComputeInstance",
    properties: {
        vmSize: "Standard_DS3_v2",
        subnet: { id: privateSubnet.id },
        sshSettings: { sshPublicAccess: "Disabled" },
    },
});
```

**Note**: Compute instances inherit encryption settings from the parent workspace configuration.

### ml-compute-internet-access

**Severity:** high · **Enforcement:** advisory

Ensure Machine Learning compute instances do not have direct internet access.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

Remediation

##### Fix: Disable Internet Access for ML Compute

Your ML compute instance has direct internet access. Deploy in a private subnet:

```typescript
const mlCompute = new azure.machinelearningservices.Compute("myMLCompute", {
    // ... other properties
    properties: {
        computeType: "AmlCompute",  // or "ComputeInstance"
        properties: {
            vmSize: "Standard_DS3_v2",
            vmPriority: "Dedicated",
            subnet: { id: privateSubnet.id },  // Deploy in VNet
            enableNodePublicIp: false,  // Disable public IP on nodes
            isolationMode: "UserDefined",  // Enhanced network isolation
        },
    },
    tags: {
        "PublicAccess": "disabled",
        "VNetIntegration": "enabled",
        "PrivateEndpoint": "configured",
    },
});
```

Ensure your VNet has appropriate NSG rules and private endpoints for required services.

### ml-workspace-cmk-configured

**Severity:** high · **Enforcement:** advisory

Ensure Machine Learning workspaces use customer-managed keys for encryption at rest.

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Keys for ML Workspace

Your Machine Learning workspace needs customer-managed key encryption:

```typescript
const mlWorkspace = new azure.machinelearningservices.Workspace("myMLWorkspace", {
    resourceGroupName: resourceGroup.name,
    workspaceName: "my-ml-workspace",
    location: "eastus",
    encryption: {
        status: "Enabled",
        keyVaultProperties: {
            keyVaultArmId: keyVault.id,
            keyIdentifier: "https://myvault.vault.azure.net/keys/mykey/version",
        },
    },
    hbiWorkspace: true,  // High Business Impact for sensitive data
    // Note: Tags removed - tag-based validation is not enforced by this policy
});
```

**Note**: Associated resources (storage, App Insights, Container Registry) should also use CMK.

### mysql-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require MySQL flexible servers to use customer-managed keys

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable MySQL Customer-Managed Keys

```typescript
const mysqlServer = new azurenative.dbformysql.Server("my-mysql-server", {
    sku: {
        tier: "GeneralPurpose",
    },
    dataEncryption: {
        type: "AzureKeyVault",  // Use customer-managed keys from Key Vault
        primaryKeyURI: key.keyUri,
        primaryUserAssignedIdentityId: identity.id,
    },
    // ... other config
});
```

### mysql-private-endpoints

**Severity:** high · **Enforcement:** advisory

Require MySQL databases to use private endpoints

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

Remediation

##### Fix: Configure MySQL with Private Endpoints

```typescript
const mysqlServer = new azurenative.dbformysql.Server("my-mysql-server", {
    sku: {
        tier: "GeneralPurpose",
    },
    network: {
        publicNetworkAccess: "Disabled",  // Disable public network access
    },
    // ... other config
});
```

### mysql-ssl-enforcement

**Severity:** high · **Enforcement:** advisory

Require MySQL databases to have SSL enforcement enabled

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable MySQL SSL Enforcement

```typescript
const requireSecureTransport = new azurenative.dbformysql.Configuration("require-secure-transport", {
    serverName: mysqlServer.name,
    configurationName: "require_secure_transport",
    value: "ON",  // Require SSL/TLS for all connections
    // ... other config
});
```

### network-interface-no-public-ip

**Severity:** critical · **Enforcement:** advisory

Require Network Interfaces to have no public IP address associations

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Remove Public IP Address from Network Interface

```typescript
const nic = new azurenative.network.NetworkInterface("my-nic", {
    ipConfigurations: [{
        privateIPAllocationMethod: "Dynamic",
        // Do NOT include publicIPAddress property
        // ... other config
    }],
});
```

### no-unrestricted-route-to-internet-gateway

**Severity:** high · **Enforcement:** advisory

Ensure route tables do not contain unrestricted routes to internet gateways for security monitoring.

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.

Remediation

##### Fix: Remove Unrestricted Internet Routes

Your Route Table contains unrestricted routes to the internet (0.0.0.0/0). This violates network segmentation best practices.

##### Option 1: Remove the Internet Route

If direct internet access isn't required, remove the route:

```typescript
const routeTable = new azure.network.RouteTable("myRouteTable", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    routes: [
        // Remove or comment out routes with 0.0.0.0/0 destination
        // {
        //     name: "internet-route",
        //     addressPrefix: "0.0.0.0/0",
        //     nextHopType: "Internet",
        // },
    ],
});
```

##### Option 2: Route Through Network Virtual Appliance

If internet access is needed, route traffic through a firewall or NVA:

```typescript
const routeTable = new azure.network.RouteTable("myRouteTable", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    routes: [
        {
            name: "internet-via-firewall",
            addressPrefix: "0.0.0.0/0",
            nextHopType: "VirtualAppliance",
            nextHopIpAddress: "10.0.1.4",  // IP of your firewall/NVA
        },
    ],
    tags: {
        MonitoringEnabled: "true",
        SecurityApproved: "true",
    },
});
```

### nsg-disallow-public-internet-ingress

**Severity:** high · **Enforcement:** advisory

Require Network Security Groups to disallow public internet ingress

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Remove Public Internet Ingress from Network Security Group

```typescript
const nsg = new azurenative.network.NetworkSecurityGroup("secure-nsg", {
    securityRules: [
        {
            protocol: "Tcp",
            sourceAddressPrefix: "203.0.113.0/24",  // Use specific IP ranges, not 0.0.0.0/0
            access: "Allow",
            direction: "Inbound",
            // ... other config
        },
    ],
});
```

### nsg-http-restriction

**Severity:** high · **Enforcement:** advisory

Require Network Security Groups to disallow inbound HTTP traffic

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Restrict Inbound HTTP Traffic in Network Security Group

```typescript
const nsg = new azurenative.network.NetworkSecurityGroup("my-nsg", {
    securityRules: [
        {
            protocol: "Tcp",
            destinationPortRange: "80",
            access: "Deny",  // Deny HTTP traffic
            direction: "Inbound",
            // ... other config
        },
        {
            protocol: "Tcp",
            destinationPortRange: "443",
            access: "Allow",  // Allow HTTPS instead
            direction: "Inbound",
            // ... other config
        },
    ],
});
```

### nsg-restrict-ingress-ssh-all

**Severity:** high · **Enforcement:** advisory

Restrict SSH access from all IPs in network security groups.

- **A.6.7 Remote working** — Security measures shall be implemented when personnel are working remotely to protect information accessed, processed or stored outside the organization's premises.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Restrict SSH Access to Specific IP Ranges

Your Network Security Group allows SSH access from all IP addresses (0.0.0.0/0, *, or "Any"). Update the security rule to allow SSH only from specific trusted IP ranges:

```typescript
const nsg = new azure.network.NetworkSecurityGroup("myNSG", {
    securityRules: [
        {
            name: "AllowSSHFromOffice",
            priority: 100,
            direction: "Inbound",
            access: "Allow",
            protocol: "Tcp",
            sourceAddressPrefix: "203.0.113.0/24",  // Your office IP range
            sourcePortRange: "*",
            destinationAddressPrefix: "*",
            destinationPortRange: "22",
        },
    ],
});
```

For multiple allowed IP ranges, use `sourceAddressPrefixes`:

```typescript
sourceAddressPrefixes: [
    "203.0.113.0/24",    // Office network
    "198.51.100.10/32",  // VPN gateway
],
```

**Do not use**: `0.0.0.0/0`, `*`, `Any`, or `Internet` as the source address prefix, as these allow SSH access from anywhere on the internet.

### nsg-ssh-rdp-restriction

**Severity:** high · **Enforcement:** advisory

Require Network Security Groups to restrict SSH and RDP access

- **A.6.7 Remote working** — Security measures shall be implemented when personnel are working remotely to protect information accessed, processed or stored outside the organization's premises.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Restrict SSH and RDP Access in Network Security Group

```typescript
const nsg = new azurenative.network.NetworkSecurityGroup("secure-nsg", {
    securityRules: [
        {
            protocol: "Tcp",
            destinationPortRange: "22",
            sourceAddressPrefix: "10.0.255.0/24",  // Restrict to Bastion subnet, not 0.0.0.0/0
            access: "Allow",
            direction: "Inbound",
            // ... other config
        },
    ],
});
```

### nsg-strict-rules

**Severity:** high · **Enforcement:** advisory

Require strict Network Security Group rules with explicit allow/deny configuration

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Configure Strict Network Security Group Rules

```typescript
const nsg = new azurenative.network.NetworkSecurityGroup("strict-nsg", {
    securityRules: [
        {
            protocol: "Tcp",
            sourceAddressPrefix: "10.0.0.0/16",  // Use specific IP ranges, not * or 0.0.0.0/0
            destinationAddressPrefix: "10.0.1.0/24",  // Use specific destinations
            access: "Allow",
            direction: "Inbound",
            // ... other config
        },
    ],
});
```

### postgresql-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require PostgreSQL flexible servers to use customer-managed keys

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Keys for PostgreSQL Flexible Server

```typescript
const server = new azurenative.dbforpostgresql.Server("my-postgres-server", {
    sku: {
        tier: "GeneralPurpose",
    },
    dataEncryption: {
        type: "AzureKeyVault",  // Use customer-managed keys from Key Vault
        primaryKeyUri: key.keyUriWithVersion,
        primaryUserAssignedIdentityId: identity.id,
    },
    // ... other config
});
```

### postgresql-private-endpoints

**Severity:** high · **Enforcement:** advisory

Require PostgreSQL databases to use private endpoints

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

Remediation

##### Fix: Configure PostgreSQL with Private Endpoints

```typescript
const server = new azurenative.dbforpostgresql.Server("my-postgres-server", {
    sku: {
        tier: "GeneralPurpose",
    },
    network: {
        publicNetworkAccess: "Disabled",  // Disable public network access
    },
    // ... other config
});
```

### postgresql-ssl-enforcement

**Severity:** high · **Enforcement:** advisory

Require PostgreSQL databases to have SSL enforcement enabled

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable SSL Enforcement for PostgreSQL

```typescript
const requireSecureTransport = new azurenative.dbforpostgresql.Configuration("require-secure-transport", {
    serverName: server.name,
    configurationName: "require_secure_transport",
    value: "ON",  // Require SSL/TLS for all connections
    // ... other config
});
```

### prohibit-hardcoded-secrets

**Severity:** critical · **Enforcement:** advisory

Prohibit hardcoded secrets in code and configuration

- **A.5.17 Authentication information** — Allocation and management of authentication information shall be controlled by a management process, including advising personnel on appropriate handling of authentication information.

Remediation

##### Fix: Remove Hardcoded Secrets

Remove hardcoded secrets from resource configuration.

##### Example Violations

**Web App with hardcoded application settings:**
```typescript
const webApp = new azurenative.web.WebApp("my-app", {
    siteConfig: {
        appSettings: [
            {
                name: "DATABASE_PASSWORD",
                value: "mySecretPassword123",  // Hardcoded secret
            },
            {
                name: "API_KEY",
                value: "sk_live_abc123def456789",  // Hardcoded secret
            },
        ],
    },
});
```

**Container Group with hardcoded environment variables:**
```typescript
const containerGroup = new azurenative.containerinstance.ContainerGroup("my-container", {
    containers: [{
        name: "app",
        environmentVariables: [
            {
                name: "DATABASE_PASSWORD",
                value: "mySecretPassword123",  // Hardcoded secret
            },
            {
                name: "API_TOKEN",
                value: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",  // Hardcoded JWT token
            },
        ],
    }],
});
```

**Web App with hardcoded connection string:**
```typescript
const webApp = new azurenative.web.WebApp("my-app", {
    siteConfig: {
        connectionStrings: [{
            name: "DefaultConnection",
            connectionString: "Server=myserver;Database=mydb;User=admin;Password=hardcodedPassword123",
        }],
    },
});
```

### rbac-least-privilege

**Severity:** critical · **Enforcement:** advisory

Enforce least privilege access control by prohibiting overly broad RBAC role assignments

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Use Specific Least-Privilege Roles

```typescript
const roleAssignment = new azurenative.authorization.RoleAssignment("my-assignment", {
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/acdd72a7-3385-48ef-bd42-f606fba81ae7",  // Reader role instead of Owner/Contributor
    principalId: servicePrincipalId,
    scope: "/subscriptions/{sub-id}/resourceGroups/my-rg",  // Scope to resource group instead of subscription
});
```

### redis-cache-non-ssl-port

**Severity:** high · **Enforcement:** advisory

Require Redis Cache to disable non-SSL port access

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Disable Non-SSL Port

```typescript
const redisCache = new azurenative.redis.Redis("my-redis-cache", {
    enableNonSslPort: false,  // Disable non-SSL port to enforce encrypted connections
    minimumTlsVersion: "1.2",  // Enforce minimum TLS 1.2
    // ... other config
});
```

### redis-cache-private-endpoints

**Severity:** high · **Enforcement:** advisory

Require Redis Cache to use private endpoints

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Private Network Access

```typescript
const redisCache = new azurenative.redis.Redis("my-redis-cache", {
    sku: {
        name: "Premium",  // Premium SKU required for private endpoints
        family: "P",
    },
    publicNetworkAccess: "Disabled",  // Disable public access
    subnetId: subnet.id,  // Deploy in subnet for network isolation
    minimumTlsVersion: "1.2",
    // ... other config
});
```

### resources-change-tracking-tags

**Severity:** low · **Enforcement:** advisory

Require all Azure resources to have proper tagging for change tracking

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Add Change Tracking Tags to Resources

```typescript
const storageAccount = new azurenative.storage.StorageAccount("app-storage", {
    sku: {
        name: "Standard_LRS",
    },
    tags: {
        "last-modified": "2025-10-07",  // ISO 8601 date format (YYYY-MM-DD)
        "modified-by": "jane.doe@company.com",
        "change-reason": "Added storage account for new application deployment",
    },
    // ... other config
});
```

### resources-cost-management-tags

**Severity:** low · **Enforcement:** advisory

Require all resources to have cost management tags

- **A.5.9 Inventory of information and other associated assets** — An inventory of information and other associated assets, including owners, shall be developed and maintained.

Remediation

##### Fix: Add Cost Management Tags

```typescript
const resource = new azurenative.web.WebApp("my-app", {
    tags: {
        "cost-center": "CC-12345",
        project: "my-project",
        owner: "team@company.com",
        team: "engineering",
    },
    // ... other config
});
```

### resources-environment-tags

**Severity:** low · **Enforcement:** advisory

Require all resources to have environment tags

- **A.5.9 Inventory of information and other associated assets** — An inventory of information and other associated assets, including owners, shall be developed and maintained.

Remediation

##### Fix: Add Environment Tag

```typescript
const resource = new azurenative.storage.StorageAccount("my-storage", {
    tags: {
        environment: "prod",  // Use "dev", "test", "staging", or "prod"
    },
    // ... other config
});
```

### search-service-encrypted-at-rest

**Severity:** high · **Enforcement:** advisory

Ensure Search Services use encryption at rest with customer-managed keys for data protection.

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Customer-Managed Key Encryption for Search Service

Your Search Service needs encryption at rest with customer-managed keys:

```typescript
const searchService = new azure.search.Service("mySearch", {
    // ... other properties
    sku: { name: "Standard" },  // Standard tier or higher required for CMK
    encryptionWithCmk: {
        enforcement: "Enabled",  // Enforce CMK encryption
    },
});

// Note: Configure Key Vault key and grant Search Service managed identity access
```

**Important**: Free and Basic SKUs don't support customer-managed keys.

### search-service-logs-monitor

**Severity:** medium · **Enforcement:** advisory

Ensure Search Service sends logs to monitoring solutions for comprehensive log analysis.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable Logging for Search Service

Your Search Service needs diagnostic logging configured:

```typescript
const diagnostics = new azure.insights.DiagnosticSetting("searchDiagnostics", {
    name: "search-logging",
    resourceUri: searchService.id,
    workspaceId: logAnalyticsWorkspace.id,
    logs: [
        {
            category: "OperationLogs",  // Search operations
            enabled: true,
            retentionPolicy: { enabled: true, days: 365 },
        },
        {
            category: "SearchSlowLogs",  // Slow query logs
            enabled: true,
            retentionPolicy: { enabled: true, days: 365 },
        },
    ],
    metrics: [{
        category: "AllMetrics",
        enabled: true,
    }],
});
```

Add tags to track logging configuration:
```typescript
tags: {
    "LoggingEnabled": "true",
    "LogAnalytics": logAnalyticsWorkspace.id,
}
```

### search-service-vnet-only

**Severity:** medium · **Enforcement:** advisory

Ensure Search Service is in VNet only.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Restrict Search Service to VNet Only

Your Search Service allows public access. Disable it and use private endpoints:

```typescript
const searchService = new azure.search.Service("mySearch", {
    // ... other properties
    sku: { name: "Standard" },  // Basic tier or higher required
    publicNetworkAccess: "disabled",  // Disable public access
    networkRuleSet: {
        bypass: "None",  // No bypass for Azure services
    },
    tags: {
        "PublicAccess": "disabled",
        "PrivateEndpoint": "configured",
        "VNetIntegration": "enabled",
    },
});

// Create private endpoint for the search service
const privateEndpoint = new azure.network.PrivateEndpoint("searchPE", {
    // ... private endpoint configuration
    privateLinkServiceConnections: [{
        name: "search-connection",
        privateLinkServiceId: searchService.id,
        groupIds: ["searchService"],
    }],
});
```

### security-center-enabled

**Severity:** high · **Enforcement:** advisory

Ensure Security Center is enabled for vulnerability management.

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable Azure Security Center

Your subscription needs Azure Security Center configured for vulnerability management:

```typescript
// Enable Security Center pricing for services
const vmPricing = new azure.security.Pricing("vmPricing", {
    pricingName: "VirtualMachines",
    pricingTier: "Standard",  // or "Free" for basic protection
});

const storagePricing = new azure.security.Pricing("storagePricing", {
    pricingName: "StorageAccounts",
    pricingTier: "Standard",
});

// Configure security contacts
const securityContact = new azure.security.SecurityContact("securityContact", {
    securityContactName: "default1",
    emails: "security@example.com",
    notificationsByRole: {
        state: "On",  // Enable email notifications
        roles: ["Owner"],  // Notify subscription admins
    },
});

// Enable auto-provisioning of security agents
const autoProvisioning = new azure.security.AutoProvisioningSetting("autoProvision", {
    settingName: "default",
    autoProvision: "On",  // Automatically deploy agents
});
```

### service-bus-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Service Bus namespace to use customer-managed keys for encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Service Bus Customer-Managed Keys

```typescript
const namespace = new azurenative.servicebus.Namespace("my-namespace", {
    sku: {
        name: "Premium",  // Premium tier required for customer-managed keys
        tier: "Premium",
    },
    encryption: {
        keySource: "Microsoft.KeyVault",  // Use Azure Key Vault for encryption keys
        keyVaultProperties: [{
            keyName: key.name,
            keyVaultUri: keyVault.properties.vaultUri,
            identity: {
                userAssignedIdentity: identity.id,
            },
        }],
    },
    // ... other config
});
```

### snapshot-configuration

**Severity:** medium · **Enforcement:** advisory

Ensure snapshots are properly configured for backup and recovery purposes.

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Snapshot Properly

Ensure your snapshot is properly configured:

```typescript
const snapshot = new azure.compute.Snapshot("disk-snapshot", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    creationData: {
        createOption: "Copy",
        sourceResourceId: disk.id,
    },
    encryption: {
        type: "EncryptionAtRestWithPlatformKey",
    },
    incremental: true,  // Use incremental snapshots for efficiency
});
```

**Note**: For automated snapshots, consider using snapshot policies or Azure Backup instead of manual snapshots.

### sql-database-backup-retention

**Severity:** medium · **Enforcement:** advisory

Require Azure SQL Database to have backup retention configured with redundant storage

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Enable SQL Database Backup Retention with Redundant Storage

```typescript
const database = new azurenative.sql.Database("my-database", {
    sku: {
        name: "S0",
        tier: "Standard",
    },
    requestedBackupStorageRedundancy: "Geo",  // Use geo-redundant backup storage
    // ... other config
});
```

### sql-database-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Azure SQL databases to use customer-managed keys for transparent data encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable SQL Database Customer-Managed Keys for TDE

```typescript
const encryptionProtector = new azurenative.sql.EncryptionProtector("tde-protector", {
    serverKeyType: "AzureKeyVault",  // Use customer-managed key from Azure Key Vault
    serverKeyName: serverKey.name,
    autoRotationEnabled: true,  // Enable auto-rotation when key version changes
    // ... other config
});
```

### sql-database-high-availability

**Severity:** medium · **Enforcement:** advisory

Require Azure SQL Database to have high availability configuration

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Enable SQL Database High Availability

```typescript
const database = new azurenative.sql.Database("my-database", {
    sku: {
        name: "P1",
        tier: "Premium",
    },
    zoneRedundant: true,  // Enable zone redundancy for high availability
    // ... other config
});
```

### sql-database-least-privilege

**Severity:** high · **Enforcement:** advisory

Ensure SQL databases use appropriate SQL-specific roles instead of broad management roles

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Use SQL DB Contributor Instead of Broad Roles

```typescript
const sqlAssignment = new azurenative.authorization.RoleAssignment("sql-access", {
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/9b7fa17d-e63e-47b0-bb0a-15c516ac86ec",  // SQL DB Contributor
    principalId: appServicePrincipalId,
    scope: "/subscriptions/{sub-id}/resourceGroups/my-rg/providers/Microsoft.Sql/servers/myserver/databases/mydb",
    // ... other config
});
```

### sql-database-tde-enabled-check

**Severity:** high · **Enforcement:** advisory

Require Azure SQL databases to enable transparent data encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Transparent Data Encryption

```typescript
const tde = new azurenative.sql.TransparentDataEncryption("tde", {
    resourceGroupName: resourceGroup.name,
    serverName: sqlServer.name,
    databaseName: database.name,
    state: "Enabled",  // Enable transparent data encryption
});
```

### sql-server-audit-logging

**Severity:** medium · **Enforcement:** advisory

Require Azure SQL Server to have audit logging enabled

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable SQL Server Audit Logging

```typescript
const auditPolicy = new azurenative.sql.ServerBlobAuditingPolicy("audit-policy", {
    state: "Enabled",  // Enable audit logging
    storageEndpoint: storageEndpoint,
    retentionDays: 90,  // Retain audit logs for 90 days
    // ... other config
});
```

### sql-server-azure-ad-authentication

**Severity:** high · **Enforcement:** advisory

Require Azure SQL Server to have Azure AD administrators configured

- **A.5.16 Identity management** — The full life cycle of identities shall be managed.
- **A.8.5 Secure authentication** — Secure authentication technologies and procedures shall be implemented based on information access restrictions and the topic-specific policy on access control.

Remediation

##### Fix: Configure Azure AD Authentication for SQL Server

```typescript
const sqlServer = new azurenative.sql.Server("my-sql-server", {
    administrators: {
        administratorType: "ActiveDirectory",
        login: "admin@contoso.com",  // Azure AD admin user or group name
        sid: "00000000-0000-0000-0000-000000000000",  // Azure AD object ID
        tenantId: "00000000-0000-0000-0000-000000000000",
        principalType: "User",
    },
    // ... other config
});
```

### sql-server-disable-public-access

**Severity:** critical · **Enforcement:** advisory

Require Azure SQL Server to disable public network access

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Disable SQL Server Public Network Access

```typescript
const sqlServer = new azurenative.sql.Server("my-sql-server", {
    publicNetworkAccess: "Disabled",  // Disable public network access
    // ... other config
});
```

### sql-server-encrypted-connections

**Severity:** high · **Enforcement:** advisory

Require Azure SQL Server to have encrypted connections with minimum TLS 1.2

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable SQL Server Encrypted Connections

```typescript
const sqlServer = new azurenative.sql.Server("my-sql-server", {
    minimalTlsVersion: "1.2",  // Enforce TLS 1.2 or higher for encrypted connections
    // ... other config
});
```

### sql-server-restrict-outbound-access

**Severity:** high · **Enforcement:** advisory

Require Azure SQL servers to restrict outbound network access to prevent data exfiltration

- **A.8.12 Data leakage prevention** — Data leakage prevention measures shall be applied to systems, networks and any other devices that process, store or transmit sensitive information.

Remediation

##### Fix: Restrict Outbound Network Access

```typescript
const sqlServer = new azurenative.sql.Server("my-sql-server", {
    restrictOutboundNetworkAccess: "Enabled",  // Restrict outbound access
    // ... other config
});
```

### storage-account-files-encryption

**Severity:** high · **Enforcement:** advisory

Require Files to have encryption enabled

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Azure Files Encryption

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    encryption: {
        services: {
            file: { enabled: true },  // Enable Azure Files encryption
        },
    },
    // ... other config
});
```

### storage-account-firewall

**Severity:** high · **Enforcement:** advisory

Require Storage Accounts to have firewall rules configured

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Configure Storage Account Firewall Rules

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    networkRuleSet: {
        defaultAction: "Deny",  // Deny by default
        ipRules: [{ value: "203.0.113.0/24" }],  // Allow specific IPs
        virtualNetworkRules: [{ id: subnet.id }],  // Allow specific subnets
    },
    // ... other config
});
```

### storage-account-geo-replication

**Severity:** medium · **Enforcement:** advisory

Require Storage Accounts to have geo-replication enabled for business continuity

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Enable Geo-Replication

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_GRS" },  // Use geo-replicated SKU for redundancy
    kind: "StorageV2",
    // ... other config
});
```

### storage-account-https-only

**Severity:** high · **Enforcement:** advisory

Require Storage Accounts to enforce HTTPS-only traffic

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable HTTPS-Only Traffic

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    enableHttpsTrafficOnly: true,  // Enforce HTTPS-only traffic
    // ... other config
});
```

### storage-account-infrastructure-encryption

**Severity:** medium · **Enforcement:** advisory

Require Storage Accounts to enable infrastructure encryption for double encryption at rest

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enable Infrastructure Encryption

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    encryption: {
        keySource: "Microsoft.Storage",
        requireInfrastructureEncryption: true,  // Enable double encryption at rest
    },
    // ... other config
});
```

### storage-account-least-privilege

**Severity:** high · **Enforcement:** advisory

Ensure storage accounts use appropriate storage-specific roles instead of broad management roles

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Use Storage Data Roles Instead of Management Roles

```typescript
const blobAssignment = new azurenative.authorization.RoleAssignment("blob-access", {
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",  // Storage Blob Data Contributor
    principalId: appPrincipalId,
    scope: storageAccount.id,
    // ... other config
});
```

### storage-account-minimum-tls

**Severity:** high · **Enforcement:** advisory

Require Storage Accounts to enforce a minimum TLS version for data in transit

- **A.5.14 Information transfer** — Information transfer rules, procedures, or agreements shall be in place for all types of transfer facilities within the organization and between the organization and other parties.
- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Enforce Minimum TLS Version

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    minimumTlsVersion: "TLS1_2",  // Require TLS 1.2 or higher
    // ... other config
});
```

### storage-account-policy-grantee

**Severity:** high · **Enforcement:** advisory

Ensure Storage Account policy grantee check.

- **A.5.15 Access control** — Rules to control physical and logical access to information and other associated assets shall be established and implemented based on business and information security requirements.
- **A.5.18 Access rights** — Access rights to information and other associated assets shall be provisioned, reviewed, modified and removed in accordance with the organization's topic-specific policy on and rules for access control.
- **A.8.2 Privileged access rights** — The allocation and use of privileged access rights shall be restricted and managed.

Remediation

##### Fix: Implement Group-Based Access Control

Your storage account has too many direct user access grants or lacks proper access control documentation.

**Solution 1**: Use Azure AD groups instead of direct user assignments:

```typescript
// Create or use existing Azure AD group
const storageUsersGroup = new azuread.Group("storageUsers", {
    displayName: "Storage Users",
    securityEnabled: true,
});

// Assign role to group instead of individual users
const roleAssignment = new azure.authorization.RoleAssignment("groupAccess", {
    resourceGroupName: resourceGroup.name,
    scope: storageAccount.id,
    principalId: storageUsersGroup.objectId,
    principalType: "Group",
    roleDefinitionId: "/providers/Microsoft.Authorization/roleDefinitions/ba92f5b4-2d11-453d-a403-e96b0029c9fe",  // Storage Blob Data Reader
});
```

**Solution 2**: Document access justification with tags:

```typescript
const storageAccount = new azure.storage.StorageAccount("myStorage", {
    resourceGroupName: resourceGroup.name,
    accountName: "mystorageaccount",
    tags: {
        AccessJustification: "Approved by Security Team - Ticket #12345",
        LastReviewed: "2024-01-15",
        LeastPrivilege: "enabled",
    },
    // ... other properties
});
```

**Best Practices**:
- Prefer group-based access over direct user assignments
- Use service principals or managed identities for applications
- Document and review privileged access grants regularly
- Implement least privilege principles

### storage-account-public-access

**Severity:** critical · **Enforcement:** advisory

Require Storage Accounts to disable public blob access

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.

Remediation

##### Fix: Disable Public Blob Access

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    allowBlobPublicAccess: false,  // Disable public blob access
    // ... other config
});
```

### storage-account-public-network-access

**Severity:** critical · **Enforcement:** advisory

Require Storage Accounts to disable public network access

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Disable Public Network Access

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: {
        name: "Standard_LRS",
    },
    kind: "StorageV2",
    publicNetworkAccess: "Disabled",  // Disable public network access
    // ... other config
});
```

### storage-account-replication-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Storage Account replication is enabled for data availability and disaster recovery.

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Configure Storage Replication for Data Resilience

Your storage account is using inadequate replication that doesn't meet the minimum requirements for data availability.

**Solution**: Use a SKU with appropriate replication:

```typescript
const storageAccount = new azure.storage.StorageAccount("myStorage", {
    resourceGroupName: resourceGroup.name,
    accountName: "mystorageaccount",
    sku: {
        name: "Standard_GRS",  // Geo-redundant storage (or RAGRS/GZRS/RAGZRS)
    },
    // ... other properties
});
```

**Replication Types** (in order of redundancy level):

- `Standard_LRS` - Locally redundant (3 copies in one datacenter)
- `Standard_ZRS` - Zone redundant (3 copies across availability zones)
- `Standard_GRS` - Geo-redundant (6 copies across two regions)
- `Standard_RAGRS` - Read-access geo-redundant (GRS + read access to secondary)
- `Standard_GZRS` - Geo-zone-redundant (combines ZRS and GRS)
- `Standard_RAGZRS` - Read-access geo-zone-redundant (GZRS + read access)

**For critical data**, use geo-redundant options (GRS, RAGRS, GZRS, or RAGZRS) to protect against regional disasters.

### storage-account-shared-key-access

**Severity:** high · **Enforcement:** advisory

Require Storage Accounts to disable shared key access in favor of Azure AD authentication

- **A.5.16 Identity management** — The full life cycle of identities shall be managed.
- **A.8.5 Secure authentication** — Secure authentication technologies and procedures shall be implemented based on information access restrictions and the topic-specific policy on access control.

Remediation

##### Fix: Disable Shared Key Access

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    allowSharedKeyAccess: false,  // Require Azure AD authentication
    // ... other config
});
```

Shared key access defaults to enabled in Azure, so it must be explicitly set to `false`.

### storage-account-uses-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Storage Accounts to use customer-managed keys for encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Customer-Managed Keys

```typescript
const storageAccount = new azurenative.storage.StorageAccount("mystorageaccount", {
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
    encryption: {
        keySource: "Microsoft.Keyvault",  // Use customer-managed keys
        keyVaultProperties: {
            keyName: "my-encryption-key",
            keyVaultUri: "https://my-keyvault.vault.azure.net/",
        },
    },
    // ... other config
});
```

### storage-account-versioning-enabled

**Severity:** medium · **Enforcement:** advisory

Perform automated backups for Storage Accounts with versioning.

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.
- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Enable Blob Versioning for Data Protection

Your storage account lacks blob versioning, which is critical for backup and recovery.

**Note**: Blob versioning is configured via the Blob Service, not the Storage Account resource directly.

**Solution**: Enable blob versioning using the BlobServiceProperties resource:

```typescript
const storageAccount = new azure.storage.StorageAccount("myStorage", {
    resourceGroupName: resourceGroup.name,
    accountName: "mystorageaccount",
    // ... other properties
});

// Enable blob versioning
const blobService = new azure.storage.BlobServiceProperties("blobService", {
    resourceGroupName: resourceGroup.name,
    accountName: storageAccount.name,
    isVersioningEnabled: true,          // Enable versioning
    deleteRetentionPolicy: {
        enabled: true,
        days: 7,                         // Soft delete retention
    },
});
```

**Lifecycle Management**: Add lifecycle policies to manage storage costs:

```typescript
const managementPolicy = new azure.storage.ManagementPolicy("lifecycle", {
    resourceGroupName: resourceGroup.name,
    accountName: storageAccount.name,
    policy: {
        rules: [{
            name: "deleteOldVersions",
            type: "Lifecycle",
            definition: {
                actions: {
                    version: {
                        delete: { daysAfterCreationGreaterThan: 90 }
                    }
                },
                filters: { blobTypes: ["blockBlob"] }
            }
        }]
    }
});
```

### storage-file-encrypted-check

**Severity:** high · **Enforcement:** advisory

Ensure Azure Storage Files have encryption enabled for data protection.

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Azure Files encryption

Set encryption on the Storage Account with Files service included. Optionally set keySource to 'Microsoft.Keyvault' if customer-managed keys are required.

### subnet-auto-assign-public-ip

**Severity:** high · **Enforcement:** advisory

Ensure subnet auto-assign public IP is disabled.

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Disable Subnet Auto-Assign Public IP

Your subnet has `defaultOutboundAccess` enabled (or not explicitly set to false), which allows automatic public IP assignment to resources. Disable this to prevent resources from receiving public IPs by default:

```typescript
const subnet = new azure.network.Subnet("mySubnet", {
    virtualNetworkName: vnet.name,
    resourceGroupName: resourceGroup.name,
    addressPrefix: "10.0.1.0/24",
    defaultOutboundAccess: false,  // Disable auto-assign public IP
    networkSecurityGroup: {
        id: nsg.id,  // Associate with NSG for traffic control
    },
});
```

If your resources need outbound internet access, use a NAT Gateway instead:

```typescript
const natGateway = new azure.network.NatGateway("myNatGateway", {
    resourceGroupName: resourceGroup.name,
    publicIpAddresses: [{ id: publicIp.id }],
});

const subnet = new azure.network.Subnet("mySubnet", {
    virtualNetworkName: vnet.name,
    resourceGroupName: resourceGroup.name,
    addressPrefix: "10.0.1.0/24",
    defaultOutboundAccess: false,
    natGateway: { id: natGateway.id },  // Use NAT Gateway for outbound
});
```

This ensures resources in the subnet don't get automatic public IPs while still allowing controlled outbound access.

### subscription-part-of-management-groups

**Severity:** medium · **Enforcement:** advisory

Ensure subscription is part of Management Groups for proper governance hierarchy.

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Associate Subscription with Management Group

Your subscription needs to be organized under a management group for proper governance:

```typescript
import * as azure from "@pulumi/azure-native";

// Create a management group
const managementGroup = new azure.management.ManagementGroup("myMgmtGroup", {
    displayName: "Production Environment",
    details: {
        parent: { id: "/providers/Microsoft.Management/managementGroups/root" },
    },
});

// Associate subscription with the management group
const mgmtGroupSubscription = new azure.management.ManagementGroupSubscription("subAssociation", {
    groupId: managementGroup.name,
});
```

**Benefits**: Centralized policy management, RBAC inheritance, and organized resource hierarchy.

### synapse-backup-enabled

**Severity:** medium · **Enforcement:** advisory

Ensure Synapse Analytics backup is enabled.

- **A.8.13 Information backup** — Backup copies of information, software and systems shall be maintained and regularly tested in accordance with the agreed topic-specific policy on backup.

Remediation

##### Fix: Configure Synapse Workspace Backups

Your Synapse workspace doesn't have proper backup configuration. While Synapse SQL pools have automatic backups, you need to document and configure backup policies:

##### For Dedicated SQL Pools (automatic backups included):

Dedicated SQL pools automatically create restore points. Configure retention:

```typescript
import * as azure from "@pulumi/azure-native";

const sqlPool = new azure.synapse.SqlPool("mySqlPool", {
    workspaceName: synapseWorkspace.name,
    resourceGroupName: resourceGroup.name,
    // ... other properties
    tags: {
        BackupEnabled: "enabled",
        BackupRetentionDays: "7",  // Document your retention policy
        AutomatedBackup: "enabled",
    },
});
```

##### For Spark Pools and workspace artifacts:

Use Git integration to back up notebooks, pipelines, and other artifacts:

```typescript
const workspace = new azure.synapse.Workspace("myWorkspace", {
    // ... other properties
    workspaceRepositoryConfiguration: {
        accountName: "myGitHubAccount",
        repositoryName: "synapse-artifacts",
        collaborationBranch: "main",
        rootFolder: "/",
        type: "WorkspaceGitHubConfiguration",
    },
    tags: {
        BackupEnabled: "enabled",
        PipelineBackup: "enabled",
    },
});
```

This ensures your Synapse artifacts are version-controlled and recoverable.

### synapse-configuration-logging

**Severity:** medium · **Enforcement:** advisory

Ensure Synapse Analytics has comprehensive configuration logging enabled for advanced log analysis.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable Synapse Workspace Configuration Logging

Your Synapse workspace doesn't have diagnostic settings configured. Enable comprehensive logging to Log Analytics:

```typescript
import * as azure from "@pulumi/azure-native";

const diagnostics = new azure.monitor.DiagnosticSetting("synapseDiagnostics", {
    resourceUri: workspace.id,
    workspaceId: logAnalyticsWorkspace.id,
    logs: [
        { category: "SynapseRbacOperations", enabled: true },
        { category: "GatewayApiRequests", enabled: true },
        { category: "BuiltinSqlReqsEnded", enabled: true },
        { category: "IntegrationPipelineRuns", enabled: true },
        { category: "IntegrationActivityRuns", enabled: true },
        { category: "IntegrationTriggerRuns", enabled: true },
    ],
    metrics: [
        { category: "AllMetrics", enabled: true },
    ],
});
```

For long-term retention, also send logs to a storage account:

```typescript
const diagnostics = new azure.monitor.DiagnosticSetting("synapseDiagnostics", {
    resourceUri: workspace.id,
    workspaceId: logAnalyticsWorkspace.id,
    storageAccountId: storageAccount.id,
    logs: [
        { category: "SynapseRbacOperations", enabled: true, retentionPolicy: { enabled: true, days: 365 } },
        { category: "GatewayApiRequests", enabled: true, retentionPolicy: { enabled: true, days: 365 } },
        { category: "BuiltinSqlReqsEnded", enabled: true, retentionPolicy: { enabled: true, days: 365 } },
    ],
    metrics: [{ category: "AllMetrics", enabled: true }],
});
```

This captures RBAC operations, API requests, SQL queries, and pipeline executions for security analysis and compliance.

### synapse-data-exfiltration-protection

**Severity:** high · **Enforcement:** advisory

Require Synapse Analytics workspaces to enable data exfiltration protection via managed virtual network

- **A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.
- **A.8.12 Data leakage prevention** — Data leakage prevention measures shall be applied to systems, networks and any other devices that process, store or transmit sensitive information.

Remediation

##### Fix: Enable Data Exfiltration Protection

```typescript
const workspace = new azurenative.synapse.Workspace("my-synapse-workspace", {
    managedVirtualNetwork: "default",
    managedVirtualNetworkSettings: {
        preventDataExfiltration: true,
        allowedAadTenantIdsForLinking: [
            "your-aad-tenant-id",
        ],
    },
    // ... other config
});
```

### synapse-public-network-access

**Severity:** high · **Enforcement:** advisory

Require Synapse Analytics workspaces to disable public network access

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Disable Public Network Access

```typescript
const workspace = new azurenative.synapse.Workspace("my-synapse-workspace", {
    publicNetworkAccess: "Disabled",  // Use private endpoints for connectivity
    // ... other config
});
```

### synapse-workspace-customer-managed-keys

**Severity:** high · **Enforcement:** advisory

Require Synapse Analytics workspaces to use customer-managed keys for encryption

- **A.8.24 Use of cryptography** — Rules for the effective use of cryptography, including cryptographic key management, shall be defined and implemented.

Remediation

##### Fix: Configure Customer-Managed Keys

```typescript
const synapseWorkspace = new azurenative.synapse.Workspace("my-synapse-workspace", {
    encryption: {
        cmk: {
            key: {
                name: "my-encryption-key",
                keyVaultUrl: "https://my-keyvault.vault.azure.net/",
            },
            kekIdentity: {
                useSystemAssignedIdentity: true,  // Or use userAssignedIdentity
            },
        },
    },
    // ... other config
});
```

### update-management-compliance

**Severity:** medium · **Enforcement:** advisory

Ensure VMs are configured for software updates through Azure Update Management to maintain current software versions and security patches.

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

Remediation

##### Fix: Configure Update Management for VM

Your VM needs proper update management configuration. Configure automatic updates in the OS profile:

##### For Windows VMs:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    osProfile: {
        // ... other properties
        windowsConfiguration: {
            enableAutomaticUpdates: true,  // Enable automatic updates
            patchSettings: {
                patchMode: "AutomaticByPlatform",  // Or "AutomaticByOS"
                automaticByPlatformSettings: {
                    rebootSetting: "IfRequired",
                },
                assessmentMode: "AutomaticByPlatform",
            },
            provisionVMAgent: true,  // Required for Update Management
        },
    },
});
```

##### For Linux VMs:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    osProfile: {
        // ... other properties
        linuxConfiguration: {
            patchSettings: {
                patchMode: "AutomaticByPlatform",  // Or "ImageDefault"
                assessmentMode: "AutomaticByPlatform",
                automaticByPlatformSettings: {
                    rebootSetting: "IfRequired",
                },
            },
            provisionVMAgent: true,  // Required for Update Management
        },
    },
});
```

**Note**: The VM Agent must be installed and running for Update Management to work properly.

### update-management-maintenance-configuration

**Severity:** high · **Enforcement:** advisory

Require stacks with virtual machines to define a Maintenance Configuration scoped for automated patching

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

Remediation

##### Fix: Create a Maintenance Configuration for Patching

```typescript
const maintenanceConfig = new azurenative.maintenance.MaintenanceConfiguration("patch-config", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    maintenanceScope: "InGuestPatch",
    extensionProperties: {
        InGuestPatchMode: "User",
    },
    startDateTime: "2025-01-15 02:00",
    duration: "03:00",
    timeZone: "UTC",
    recurEvery: "Week Sunday",
});
```

### update-management-patch-compliant

**Severity:** high · **Enforcement:** advisory

Ensure Update Management managed instances have patch compliance.

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

Remediation

##### Fix: Enable Update Management Patch Compliance

Your VM needs proper patch management configuration. Configure automatic patching:

##### For Windows VMs:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    osProfile: {
        // ... other properties
        windowsConfiguration: {
            enableAutomaticUpdates: true,
            patchSettings: {
                patchMode: "AutomaticByPlatform",
                automaticByPlatformSettings: {
                    rebootSetting: "IfRequired",
                },
            },
        },
    },
});
```

##### For Linux VMs:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    osProfile: {
        // ... other properties
        linuxConfiguration: {
            patchSettings: {
                patchMode: "AutomaticByPlatform",
                assessmentMode: "AutomaticByPlatform",
            },
        },
    },
});
```

##### For VM Scale Sets:

```typescript
const vmss = new azure.compute.VirtualMachineScaleSet("my-vmss", {
    // ... other properties
    virtualMachineProfile: {
        osProfile: {
            windowsConfiguration: {
                enableAutomaticUpdates: true,
                patchSettings: {
                    patchMode: "AutomaticByPlatform",
                },
            },
        },
    },
    automaticRepairsPolicy: {
        enabled: true,
        gracePeriod: "PT10M",
    },
});
```

##### Create an Automation Account for centralized management:

```typescript
const automationAccount = new azure.automation.AutomationAccount("update-automation", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Basic",
    },
});

// Link to Log Analytics workspace for monitoring
const linkedService = new azure.operationalinsights.LinkedService("automation-link", {
    resourceGroupName: resourceGroup.name,
    workspaceName: logAnalyticsWorkspace.name,
    resourceId: automationAccount.id,
});
```

### vm-approved-images

**Severity:** medium · **Enforcement:** advisory

Require pre-approved hardened VM images from trusted publishers

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Use Approved VM Images

```typescript
const vm = new azurenative.compute.VirtualMachine("my-vm", {
    hardwareProfile: { vmSize: "Standard_D2s_v3" },
    storageProfile: {
        imageReference: {
            publisher: "Canonical",              // Use approved publisher
            offer: "UbuntuServer",               // Use approved offer
            sku: "20.04-LTS",                    // Use approved SKU
            version: "latest",
        },
        // ... other config
    },
    // ... other config
});
```

### vm-detailed-monitoring

**Severity:** medium · **Enforcement:** advisory

Ensure Virtual Machines have detailed monitoring enabled for security and operational visibility.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable Detailed Monitoring for VM

Your VM lacks proper monitoring configuration. Enable detailed monitoring for security and operational visibility.

**Note**: Monitoring agent configuration cannot be validated from VM properties alone. Use VM extensions or Azure Policy to enforce monitoring agent deployment.

##### Enable Boot Diagnostics

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    diagnosticsProfile: {
        bootDiagnostics: {
            enabled: true,
            storageUri: storageAccount.primaryBlobEndpoint,  // Optional: specify storage account
        },
    },
});
```

##### Install Monitoring Agents via Extensions

For comprehensive monitoring, install the Azure Monitor Agent or Log Analytics Agent using VM extensions:

```typescript
const workspace = new azure.operationalinsights.Workspace("monitoring-workspace", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "PerGB2018",
    },
});

// For Linux VMs
const monitoringExtension = new azure.compute.VirtualMachineExtension("monitoring-ext", {
    resourceGroupName: resourceGroup.name,
    vmName: vm.name,
    publisher: "Microsoft.Azure.Monitor",
    type: "AzureMonitorLinuxAgent",
    typeHandlerVersion: "1.0",
    autoUpgradeMinorVersion: true,
    settings: {
        workspaceId: workspace.customerId,
    },
    protectedSettings: {
        workspaceKey: workspace.primarySharedKey,
    },
});
```

### vm-in-vnet

**Severity:** medium · **Enforcement:** advisory

Ensure Virtual Machines are deployed within a Virtual Network for secure network isolation.

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.
- **A.8.22 Segregation of networks** — Groups of information services, users and information systems shall be segregated in the organization's networks.

Remediation

##### Fix: Deploy VM in Virtual Network

Your VM must be deployed within a Virtual Network (VNet) for network isolation. Configure network interfaces properly:

1. Create a VNet and subnet:

```typescript
const vnet = new azure.network.VirtualNetwork("my-vnet", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    addressSpace: {
        addressPrefixes: ["10.0.0.0/16"],
    },
});

const subnet = new azure.network.Subnet("my-subnet", {
    resourceGroupName: resourceGroup.name,
    virtualNetworkName: vnet.name,
    addressPrefix: "10.0.1.0/24",
});
```

2. Create a network interface attached to the subnet:

```typescript
const nic = new azure.network.NetworkInterface("my-nic", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    ipConfigurations: [{
        name: "ipconfig1",
        subnet: {
            id: subnet.id,
        },
        privateIPAllocationMethod: "Dynamic",
    }],
});
```

3. Attach the network interface to your VM:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    networkProfile: {
        networkInterfaces: [{
            id: nic.id,
            primary: true,
        }],
    },
    // ... other properties
});
```

Note: Ensure you're using Azure Resource Manager (ARM) deployment model, not the classic deployment model.

### vm-managed-identity

**Severity:** medium · **Enforcement:** advisory

Ensure Virtual Machines have managed identity attached.

- **A.5.16 Identity management** — The full life cycle of identities shall be managed.
- **A.5.17 Authentication information** — Allocation and management of authentication information shall be controlled by a management process, including advising personnel on appropriate handling of authentication information.

Remediation

##### Fix: Enable Managed Identity for Virtual Machine

Your VM does not have managed identity configured. Enable managed identity to eliminate the need for storing credentials:

1. Configure system-assigned managed identity (recommended):

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    identity: {
        type: "SystemAssigned",
    },
});
```

2. Alternatively, use user-assigned managed identity:

```typescript
const userIdentity = new azure.managedidentity.UserAssignedIdentity("my-identity", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
});

const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    identity: {
        type: "UserAssigned",
        userAssignedIdentities: {
            [userIdentity.id]: {},
        },
    },
});
```

3. For maximum flexibility, use both system-assigned and user-assigned:

```typescript
const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    identity: {
        type: "SystemAssigned,UserAssigned",
        userAssignedIdentities: {
            [userIdentity.id]: {},
        },
    },
});
```

After enabling managed identity, you can grant the VM access to Azure resources without storing credentials in your code.

### vm-no-public-ip

**Severity:** high · **Enforcement:** advisory

Ensure Virtual Machines have no public IP.

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Remove Public IP from Virtual Machine

Your VM has a public IP address which increases attack surface. Remove it and use secure access methods:

1. Create VM without public IP address:

```typescript
const nic = new azure.network.NetworkInterface("my-nic", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    ipConfigurations: [{
        name: "ipconfig1",
        subnet: {
            id: subnet.id,
        },
        privateIPAllocationMethod: "Dynamic",
        // Do NOT add publicIPAddress here
    }],
});

const vm = new azure.compute.VirtualMachine("my-vm", {
    // ... other properties
    networkProfile: {
        networkInterfaces: [{
            id: nic.id,
        }],
    },
});
```

2. Use Azure Bastion for secure RDP/SSH access (recommended):

```typescript
const bastionSubnet = new azure.network.Subnet("AzureBastionSubnet", {
    resourceGroupName: resourceGroup.name,
    virtualNetworkName: vnet.name,
    addressPrefix: "10.0.255.0/27",  // Must be /27 or larger
});

const bastionPublicIp = new azure.network.PublicIPAddress("bastion-ip", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Standard",
    },
    publicIPAllocationMethod: "Static",
});

const bastion = new azure.network.BastionHost("my-bastion", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    ipConfigurations: [{
        name: "ipconfig",
        subnet: {
            id: bastionSubnet.id,
        },
        publicIPAddress: {
            id: bastionPublicIp.id,
        },
    }],
});
```

3. Use NAT Gateway for outbound internet access only:

```typescript
const natGatewayPublicIp = new azure.network.PublicIPAddress("nat-ip", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Standard",
    },
    publicIPAllocationMethod: "Static",
});

const natGateway = new azure.network.NatGateway("my-nat", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Standard",
    },
    publicIpAddresses: [{
        id: natGatewayPublicIp.id,
    }],
});

const subnet = new azure.network.Subnet("my-subnet", {
    resourceGroupName: resourceGroup.name,
    virtualNetworkName: vnet.name,
    addressPrefix: "10.0.1.0/24",
    natGateway: {
        id: natGateway.id,
    },
});
```

### vm-requires-managed-disks

**Severity:** medium · **Enforcement:** advisory

Require VMs to use managed disks only

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Configure VM to Use Managed Disks

```typescript
const vm = new azurenative.compute.VirtualMachine("my-vm", {
    hardwareProfile: { vmSize: "Standard_D2s_v3" },
    storageProfile: {
        osDisk: {
            createOption: "FromImage",
            managedDisk: {  // Use managed disk, not vhd property
                storageAccountType: "Premium_LRS",
            },
        },
        dataDisks: [{
            lun: 0,
            createOption: "Empty",
            diskSizeGB: 128,
            managedDisk: {  // Use managed disk, not vhd property
                storageAccountType: "Premium_LRS",
            },
        }],
        // ... other config
    },
    // ... other config
});
```

### vm-scale-set-automatic-os-upgrades

**Severity:** medium · **Enforcement:** advisory

Require VM Scale Sets to have automatic OS upgrades enabled

- **A.8.8 Management of technical vulnerabilities** — Information about technical vulnerabilities of information systems in use shall be obtained, the organization's exposure to such vulnerabilities shall be evaluated and appropriate measures shall be taken.

Remediation

##### Fix: Enable Automatic OS Upgrades for VM Scale Set

```typescript
const vmss = new azurenative.compute.VirtualMachineScaleSet("my-vmss", {
    sku: { name: "Standard_D2s_v3", capacity: 3 },
    upgradePolicy: {
        mode: "Rolling",  // Use Rolling or Automatic mode
        automaticOSUpgradePolicy: {
            enableAutomaticOSUpgrade: true,  // Enable automatic OS upgrades
            disableAutomaticRollback: false,  // Allow automatic rollback on failures
        },
    },
    // ... other config
});
```

### vm-scale-set-multi-az

**Severity:** medium · **Enforcement:** advisory

Require VM Scale Sets to span multiple availability zones

- **A.8.14 Redundancy of information processing facilities** — Information processing facilities shall be implemented with redundancy sufficient to meet availability requirements.

Remediation

##### Fix: Configure VM Scale Set for Multiple Availability Zones

```typescript
const vmss = new azurenative.compute.VirtualMachineScaleSet("my-vmss", {
    sku: { name: "Standard_D2s_v3", capacity: 3 },
    zones: ["1", "2", "3"],  // Deploy across multiple availability zones
    zoneBalance: true,       // Ensure even distribution across zones
    // ... other config
});
```

### vm-scale-set-no-public-ip

**Severity:** critical · **Enforcement:** advisory

Require VM Scale Sets to have no public IP addresses

- **A.8.3 Information access restriction** — Access to information and other associated assets shall be restricted in accordance with the established topic-specific policy on access control.
- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Remove Public IP Configuration from VM Scale Set

```typescript
const vmss = new azurenative.compute.VirtualMachineScaleSet("my-vmss", {
    sku: { name: "Standard_D2s_v3" },
    virtualMachineProfile: {
        networkProfile: {
            networkInterfaceConfigurations: [{
                name: "vmss-nic",
                primary: true,
                ipConfigurations: [{
                    name: "ipconfig1",
                    subnet: { id: subnet.id },
                    // Do NOT include publicIPAddressConfiguration
                }],
            }],
        },
        // ... other config
    },
});
```

### vm-scale-set-require-managed-disks

**Severity:** medium · **Enforcement:** advisory

Require VM Scale Sets to use managed disks only

- **A.8.9 Configuration management** — Configurations, including security configurations, of hardware, software, services and networks shall be established, documented, implemented, monitored and reviewed.

Remediation

##### Fix: Configure VM Scale Set to Use Managed Disks

```typescript
const scaleSet = new azurenative.compute.VirtualMachineScaleSet("my-scale-set", {
    sku: { name: "Standard_D2s_v3" },
    virtualMachineProfile: {
        storageProfile: {
            osDisk: {
                createOption: "FromImage",
                managedDisk: {
                    storageAccountType: "Premium_LRS",  // Use managed disk for OS disk
                },
                // Do NOT use vhdContainers property
            },
            dataDisks: [{
                lun: 0,
                createOption: "Empty",
                diskSizeGB: 128,
                managedDisk: {
                    storageAccountType: "Premium_LRS",  // Use managed disk for data disks
                },
            }],
            // ... other config
        },
        // ... other config
    },
});
```

### vmss-load-balancer-healthcheck-required

**Severity:** medium · **Enforcement:** advisory

Ensure VM Scale Sets have Load Balancer health check required for availability monitoring.

- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Configure Load Balancer with Health Checks for VM Scale Set

Your VM Scale Set lacks load balancer association with health checks. Configure it properly:

1. Create a Load Balancer with health probes:

```typescript
const lb = new azure.network.LoadBalancer("my-lb", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Standard",
    },
    frontendIPConfigurations: [{
        name: "frontend",
        subnet: {
            id: subnet.id,
        },
    }],
    probes: [{
        name: "health-probe",
        protocol: "Http",  // or "Https", "Tcp"
        port: 80,
        requestPath: "/health",  // For HTTP/HTTPS
        intervalInSeconds: 15,
        numberOfProbes: 2,
    }],
    backendAddressPools: [{
        name: "backend-pool",
    }],
    loadBalancingRules: [{
        name: "lb-rule",
        protocol: "Tcp",
        frontendPort: 80,
        backendPort: 80,
        frontendIPConfiguration: {
            id: pulumi.interpolate`${lb.id}/frontendIPConfigurations/frontend`,
        },
        backendAddressPool: {
            id: pulumi.interpolate`${lb.id}/backendAddressPools/backend-pool`,
        },
        probe: {
            id: pulumi.interpolate`${lb.id}/probes/health-probe`,
        },
    }],
});
```

2. Associate VM Scale Set with the Load Balancer:

```typescript
const vmss = new azure.compute.VirtualMachineScaleSet("my-vmss", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Standard_B2s",
        tier: "Standard",
        capacity: 2,
    },
    virtualMachineProfile: {
        networkProfile: {
            networkInterfaceConfigurations: [{
                name: "nic-config",
                primary: true,
                ipConfigurations: [{
                    name: "ip-config",
                    subnet: {
                        id: subnet.id,
                    },
                    loadBalancerBackendAddressPools: [{
                        id: pulumi.interpolate`${lb.id}/backendAddressPools/backend-pool`,
                    }],
                }],
            }],
        },
        // ... other properties
    },
});
```

3. Alternatively, use Application Gateway with health probes:

```typescript
const appGw = new azure.network.ApplicationGateway("my-appgw", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: {
        name: "Standard_v2",
        tier: "Standard_v2",
        capacity: 2,
    },
    probes: [{
        name: "health-probe",
        protocol: "Http",
        path: "/health",
        interval: 30,
        timeout: 30,
        unhealthyThreshold: 3,
        host: "localhost",
    }],
    // ... other configuration
});
```

4. Add Application Health Extension to VM Scale Set for enhanced monitoring:

```typescript
const vmss = new azure.compute.VirtualMachineScaleSet("my-vmss", {
    // ... other properties
    virtualMachineProfile: {
        extensionProfile: {
            extensions: [{
                name: "HealthExtension",
                publisher: "Microsoft.ManagedServices",
                type: "ApplicationHealthLinux",  // or ApplicationHealthWindows
                typeHandlerVersion: "1.0",
                autoUpgradeMinorVersion: true,
                settings: {
                    protocol: "http",
                    port: 80,
                    requestPath: "/health",
                },
            }],
        },
        // ... other properties
    },
});
```

### vnet-ddos-protection

**Severity:** high · **Enforcement:** advisory

Require Virtual Networks to have DDoS Protection Standard enabled

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Enable DDoS Protection Standard on Virtual Network

```typescript
const vnet = new azurenative.network.VirtualNetwork("my-vnet", {
    enableDdosProtection: true,  // Enable DDoS protection
    ddosProtectionPlan: {
        id: ddosProtectionPlan.id,  // Reference DDoS Protection Plan for Standard tier
    },
    // ... other config
});
```

### vnet-flow-logs-enabled

**Severity:** medium · **Enforcement:** advisory

Collect audit logs from VNet flow logs for network monitoring.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.

Remediation

##### Fix: Enable VNet Flow Logs for Network Monitoring

Your Virtual Network does not have flow logs configured for security monitoring and audit collection. Enable flow logs to track network traffic:

##### Step 1: Create a Network Watcher (if not exists)

```typescript
const networkWatcher = new azure.network.NetworkWatcher("myNetworkWatcher", {
    resourceGroupName: resourceGroup.name,
    location: "eastus",
});
```

##### Step 2: Create a Storage Account for Flow Logs

```typescript
const storageAccount = new azure.storage.StorageAccount("flowlogsstorage", {
    resourceGroupName: resourceGroup.name,
    kind: "StorageV2",
    sku: { name: "Standard_LRS" },
});
```

##### Step 3: Create a Log Analytics Workspace (recommended)

```typescript
const workspace = new azure.operationalinsights.Workspace("myWorkspace", {
    resourceGroupName: resourceGroup.name,
    sku: { name: "PerGB2018" },
    retentionInDays: 30,
});
```

##### Step 4: Enable Flow Logs on Your VNet/NSG

```typescript
const flowLog = new azure.network.FlowLog("myFlowLog", {
    networkWatcherName: networkWatcher.name,
    resourceGroupName: resourceGroup.name,
    targetResourceId: nsg.id,  // Or vnet.id for VNet flow logs
    storageId: storageAccount.id,
    enabled: true,
    retentionPolicy: {
        enabled: true,
        days: 30,
    },
    flowAnalyticsConfiguration: {
        networkWatcherFlowAnalyticsConfiguration: {
            enabled: true,
            workspaceResourceId: workspace.id,
            trafficAnalyticsInterval: 10,
        },
    },
});
```

This captures all network traffic for security analysis and compliance audit trails.

### vnet-nsg-associated-to-nic

**Severity:** medium · **Enforcement:** advisory

Ensure VNet network security groups are associated with network interfaces to maintain proper security controls.

- **A.8.20 Networks security** — Networks and network devices shall be secured, managed and controlled to protect information in systems and applications.

Remediation

##### Fix: Associate Network Security Group to Network Interface

Your Network Interface doesn't have a Network Security Group (NSG) associated with it. NSGs provide network-level access control for your resources.

##### Associate NSG to Network Interface

```typescript
const nsg = new azure.network.NetworkSecurityGroup("myNSG", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    securityRules: [
        {
            name: "AllowHTTPS",
            priority: 100,
            direction: "Inbound",
            access: "Allow",
            protocol: "Tcp",
            sourcePortRange: "*",
            destinationPortRange: "443",
            sourceAddressPrefix: "*",
            destinationAddressPrefix: "*",
        },
    ],
});

const nic = new azure.network.NetworkInterface("myNIC", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    networkSecurityGroup: {
        id: nsg.id,
    },
    ipConfigurations: [{
        name: "ipconfig1",
        subnet: { id: subnet.id },
        privateIPAllocationMethod: "Dynamic",
    }],
});
```

**Note**: You can associate NSGs at either the NIC level or the subnet level. NIC-level NSGs provide more granular control, while subnet-level NSGs apply to all resources in the subnet.

### vnet-nsg-unused

**Severity:** low · **Enforcement:** advisory

Ensure VNet network security groups are not unused to maintain asset inventory hygiene.

- **A.5.9 Inventory of information and other associated assets** — An inventory of information and other associated assets, including owners, shall be developed and maintained.

Remediation

##### Fix: Remove Unused Network Security Group

Your Network Security Group is not associated with any subnet or network interface. Unused NSGs create management overhead and potential security risks.

##### Option 1: Associate NSG with a Subnet

```typescript
const subnet = new azure.network.Subnet("mySubnet", {
    resourceGroupName: resourceGroup.name,
    virtualNetworkName: vnet.name,
    addressPrefix: "10.0.1.0/24",
    networkSecurityGroup: {
        id: nsg.id,
    },
});
```

##### Option 2: Associate NSG with a Network Interface

```typescript
const nic = new azure.network.NetworkInterface("myNIC", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    networkSecurityGroup: {
        id: nsg.id,
    },
    ipConfigurations: [{
        name: "ipconfig1",
        subnet: { id: subnet.id },
    }],
});
```

##### Option 3: Delete Unused NSG

If the NSG is not needed, remove it from your Pulumi program:

```typescript
// Remove or comment out the unused NSG resource
// const nsg = new azure.network.NetworkSecurityGroup("unusedNSG", {
//     ...
// });
```

**Note**: Before deleting an NSG, verify it's not referenced by any resources outside your Pulumi program.

### vnet-public-ip-associated

**Severity:** low · **Enforcement:** advisory

Ensure VNet public IPs are associated with resources to maintain asset inventory hygiene.

- **A.5.9 Inventory of information and other associated assets** — An inventory of information and other associated assets, including owners, shall be developed and maintained.

Remediation

##### Fix: Associate Public IP with a Resource

Your Public IP Address is not associated with any resource. Unassociated public IPs incur costs and create potential security risks.

##### Option 1: Associate with Network Interface

```typescript
const publicIP = new azure.network.PublicIPAddress("myPublicIP", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    publicIPAllocationMethod: "Static",
    sku: { name: "Standard" },
});

const nic = new azure.network.NetworkInterface("myNIC", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    ipConfigurations: [{
        name: "ipconfig1",
        subnet: { id: subnet.id },
        publicIPAddress: {
            id: publicIP.id,
        },
        privateIPAllocationMethod: "Dynamic",
    }],
});
```

##### Option 2: Associate with Load Balancer

```typescript
const loadBalancer = new azure.network.LoadBalancer("myLB", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    frontendIPConfigurations: [{
        name: "frontend",
        publicIPAddress: {
            id: publicIP.id,
        },
    }],
});
```

##### Option 3: Delete Unused Public IP

If not needed, remove it from your Pulumi program:

```typescript
// Remove or comment out the unused Public IP resource
// const publicIP = new azure.network.PublicIPAddress("unusedIP", {
//     ...
// });
```

**Note**: Unused public IPs incur charges. Delete them if they're not needed to reduce costs and attack surface.

### wafv2-logging-enabled

**Severity:** high · **Enforcement:** advisory

Collect audit logs from Web Application Firewall v2 for security monitoring.

- **A.8.15 Logging** — Logs that record activities, exceptions, faults and other relevant events shall be produced, stored, protected and analysed.
- **A.8.16 Monitoring activities** — Networks, systems and applications shall be monitored for anomalous behaviour and appropriate actions taken to evaluate potential information security incidents.

Remediation

##### Fix: Enable WAF v2 Audit Logging

Your Application Gateway WAF v2 doesn't have comprehensive audit logging configured. WAF logs are essential for threat detection and compliance.

##### Configure WAF v2 Diagnostic Settings

```typescript
const logAnalyticsWorkspace = new azure.operationalinsights.Workspace("logs", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: { name: "PerGB2018" },
});

const appGateway = new azure.network.ApplicationGateway("myGateway", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,

    // Use WAF_v2 SKU
    sku: {
        name: "WAF_v2",
        tier: "WAF_v2",
        capacity: 2,
    },

    webApplicationFirewallConfiguration: {
        enabled: true,
        firewallMode: "Prevention",
        ruleSetType: "OWASP",
        ruleSetVersion: "3.2",
    },
});

const diagnosticSetting = new azure.monitor.DiagnosticSetting("waf-diagnostics", {
    resourceUri: appGateway.id,
    workspaceId: logAnalyticsWorkspace.id,

    logs: [
        {
            category: "ApplicationGatewayAccessLog",
            enabled: true,
            retentionPolicy: { enabled: true, days: 30 },
        },
        {
            category: "ApplicationGatewayFirewallLog",
            enabled: true,
            retentionPolicy: { enabled: true, days: 30 },
        },
        {
            category: "ApplicationGatewayPerformanceLog",
            enabled: true,
            retentionPolicy: { enabled: true, days: 30 },
        },
    ],

    metrics: [{
        category: "AllMetrics",
        enabled: true,
    }],
});
```

##### Add Storage Account for Long-Term Retention

```typescript
const storageAccount = new azure.storage.StorageAccount("waflogstorage", {
    resourceGroupName: resourceGroup.name,
    location: resourceGroup.location,
    sku: { name: "Standard_LRS" },
    kind: "StorageV2",
});

const diagnosticSetting = new azure.monitor.DiagnosticSetting("waf-diagnostics", {
    resourceUri: appGateway.id,
    workspaceId: logAnalyticsWorkspace.id,
    storageAccountId: storageAccount.id,  // For long-term retention

    logs: [
        { category: "ApplicationGatewayAccessLog", enabled: true },
        { category: "ApplicationGatewayFirewallLog", enabled: true },
        { category: "ApplicationGatewayPerformanceLog", enabled: true },
    ],
});
```

**Note**: WAF v2 provides enhanced threat detection. Ensure your Application Gateway uses the WAF_v2 SKU tier for full functionality.

### web-app-auth-settings

**Severity:** high · **Enforcement:** advisory

Require WebApp to have proper authentication settings configured

- **A.5.16 Identity management** — The full life cycle of identities shall be managed.
- **A.8.5 Secure authentication** — Secure authentication technologies and procedures shall be implemented based on information access restrictions and the topic-specific policy on access control.

Remediation

##### Fix: Configure Authentication Settings

```typescript
const authSettings = new azurenative.web.WebAppAuthSettings("mywebapp-auth", {
    enabled: true,  // Enable authentication
    defaultProvider: "AzureActiveDirectory",
    unauthenticatedClientAction: "RedirectToLoginPage",
    tokenStoreEnabled: true,  // Enable secure token management
    azureActiveDirectoryProvider: {
        enabled: true,
        registration: {
            clientId: aadClientId,
        },
    },
    // ... other config
});
```


