Microsoft Azureintermediate

Microsoft Defender for Cloud CIS Benchmark Compliance Guide

Complete guide to implementing CIS Azure Foundations Benchmark compliance with Microsoft Defender for Cloud, including compliance dashboard, controls, remediation, and Secure Score.

10 min readUpdated 2026-01-14

Microsoft Defender for Cloud provides built-in compliance assessment against the CIS Azure Foundations Benchmark, helping organizations measure and improve their security posture. This guide covers enabling CIS compliance monitoring, understanding controls, implementing remediation, and tracking progress through Secure Score.

This article is part of our comprehensive guide on Cloud Security Tips for 2026, which covers essential security practices across all major cloud platforms.

Overview

The CIS Azure Foundations Benchmark in Defender for Cloud includes:

  • 100+ controls across Azure services
  • Automated assessment of configuration compliance
  • Remediation guidance for each control
  • Compliance scoring with trend tracking
  • Export capabilities for audit reports

Prerequisites

Before implementing CIS compliance, ensure you have:

  • Microsoft Defender for Cloud enabled on your subscription
  • Security Reader or Security Admin role
  • Azure CLI installed (version 2.50 or later)
  • Understanding of your compliance requirements
  • Remediation permissions (Contributor role for fixes)

Step 1: Enable CIS Benchmark Assessment

Enable via Azure Portal

  1. Sign in to the Azure Portal
  2. Navigate to Microsoft Defender for Cloud
  3. Go to Environment settings
  4. Select your subscription
  5. Click Security policy
  6. Under Regulatory compliance, click Add more standards
  7. Find CIS Microsoft Azure Foundations Benchmark and click Add
  8. Select the benchmark version (latest recommended)
  9. Click Save

Enable via Azure CLI

# Get subscription ID
SUBSCRIPTION_ID=$(az account show --query id -o tsv)

# List available regulatory compliance standards
az security regulatory-compliance-standards list \
  --query "[].{Name:name, State:state}" \
  -o table

# Enable CIS Azure Foundations Benchmark v2.0
az security regulatory-compliance-standards update \
  --name "CIS-Azure-2.0.0" \
  --state Enabled

# Verify enablement
az security regulatory-compliance-standards show \
  --name "CIS-Azure-2.0.0" \
  --query "{Name:name, State:state}"

Enable via REST API

# Enable CIS benchmark using REST API
az rest \
  --method PUT \
  --url "https://management.azure.com/subscriptions/$SUBSCRIPTION_ID/providers/Microsoft.Security/regulatoryComplianceStandards/CIS-Azure-2.0.0?api-version=2019-01-01-preview" \
  --body '{"properties": {"state": "Enabled"}}'

Step 2: Review Compliance Dashboard

Access Regulatory Compliance Dashboard

  1. In Defender for Cloud, go to Regulatory compliance
  2. View compliance overview:
    • Overall compliance percentage
    • Passed vs. failed controls
    • Controls by severity
  3. Select CIS Microsoft Azure Foundations Benchmark
  4. Review control families:
    • Identity and Access Management
    • Security Center
    • Storage Accounts
    • Database Services
    • Logging and Monitoring
    • Networking
    • Virtual Machines
    • Other Security Considerations

Query Compliance via Azure CLI

# Get overall compliance state for CIS benchmark
az security regulatory-compliance-standards show \
  --name "CIS-Azure-2.0.0" \
  --query "{Standard:name, Passed:passedControls, Failed:failedControls, Skipped:skippedControls}"

# List all CIS controls and their state
az security regulatory-compliance-controls list \
  --standard-name "CIS-Azure-2.0.0" \
  --query "[].{Control:name, Description:description, State:state}" \
  -o table

# Get failed controls only
az security regulatory-compliance-controls list \
  --standard-name "CIS-Azure-2.0.0" \
  --query "[?state=='Failed'].{Control:name, Description:description}" \
  -o table

Query with Azure Resource Graph

# Comprehensive CIS compliance query
az graph query -q "
  securityresources
  | where type == 'microsoft.security/regulatorycompliancestandards/regulatorycompliancecontrols'
  | where name contains 'CIS'
  | extend controlState = tostring(properties.state)
  | extend controlName = tostring(properties.description)
  | summarize Passed=countif(controlState == 'Passed'),
              Failed=countif(controlState == 'Failed'),
              Skipped=countif(controlState == 'Skipped')
"

# Get non-compliant assessments with affected resources
az graph query -q "
  securityresources
  | where type == 'microsoft.security/regulatorycompliancestandards/regulatorycompliancecontrols/regulatorycomplianceassessments'
  | where properties.state == 'Failed'
  | extend control = tostring(split(id, '/')[10])
  | extend assessment = tostring(properties.description)
  | extend resourceCount = toint(properties.failedResources)
  | project control, assessment, resourceCount
  | order by resourceCount desc
"

Step 3: Understand CIS Control Categories

Identity and Access Management (Section 1)

Control IDDescriptionLevel
1.1Ensure Security Defaults is enabledL1
1.2Ensure MFA is enabled for all usersL1
1.3Ensure guest users are reviewed monthlyL1
1.4Ensure no custom subscription owner rolesL1
1.5Enable Conditional Access policiesL2

Defender for Cloud (Section 2)

Control IDDescriptionLevel
2.1Enable enhanced security featuresL2
2.2Enable auto provisioning of agentsL1
2.3Configure email notificationsL1
2.4Enable integration with Microsoft DefenderL2

Storage Accounts (Section 3)

Control IDDescriptionLevel
3.1Require secure transferL1
3.2Enable infrastructure encryptionL2
3.3Enable soft delete for blob dataL1
3.4Use private endpointsL2
3.5Disable public blob accessL1

Database Services (Section 4)

Control IDDescriptionLevel
4.1Enable auditing on SQL serversL1
4.2Enable threat detection on SQLL2
4.3Enable TDE with customer-managed keysL2
4.4Configure SQL firewall rulesL1

Logging and Monitoring (Section 5)

Control IDDescriptionLevel
5.1Enable diagnostic settingsL1
5.2Configure activity log alertsL1
5.3Enable Network WatcherL2
5.4Configure log retentionL1

Step 4: Remediate Non-Compliant Controls

View Control Details

  1. In Regulatory compliance, click on a failed control
  2. Review:
    • Control description and requirements
    • Affected assessments
    • Non-compliant resources
    • Remediation guidance

Remediation Examples

Enable Secure Transfer for Storage (3.1):

# List storage accounts without secure transfer
az storage account list \
  --query "[?enableHttpsTrafficOnly==\`false\`].{Name:name, ResourceGroup:resourceGroup}" \
  -o table

# Enable secure transfer
az storage account update \
  --name "mystorageaccount" \
  --resource-group "rg-production" \
  --https-only true

Configure SQL Auditing (4.1):

# Enable auditing on SQL server
STORAGE_ACCOUNT="stauditlogs"
SQL_SERVER="sql-production"

az sql server audit-policy update \
  --resource-group "rg-databases" \
  --server $SQL_SERVER \
  --state Enabled \
  --storage-account $STORAGE_ACCOUNT \
  --retention-days 90

# Enable blob auditing for database
az sql db audit-policy update \
  --resource-group "rg-databases" \
  --server $SQL_SERVER \
  --database "mydb" \
  --state Enabled

Enable Activity Log Alerts (5.2):

# Create action group
az monitor action-group create \
  --resource-group "rg-monitoring" \
  --name "ag-security-alerts" \
  --short-name "SecAlerts" \
  --email-receivers name="SecurityTeam" email-address="[email protected]"

# Create activity log alert for security policy changes
az monitor activity-log alert create \
  --resource-group "rg-monitoring" \
  --name "alert-policy-changes" \
  --action-group "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/rg-monitoring/providers/Microsoft.Insights/actionGroups/ag-security-alerts" \
  --condition category=Security \
  --scope "/subscriptions/$SUBSCRIPTION_ID"

# Create alert for network security group changes
az monitor activity-log alert create \
  --resource-group "rg-monitoring" \
  --name "alert-nsg-changes" \
  --action-group "/subscriptions/$SUBSCRIPTION_ID/resourceGroups/rg-monitoring/providers/Microsoft.Insights/actionGroups/ag-security-alerts" \
  --condition category=Administrative and operationName="Microsoft.Network/networkSecurityGroups/write" \
  --scope "/subscriptions/$SUBSCRIPTION_ID"

Enable MFA for Users (1.2):

# Check Conditional Access MFA policy status
az rest \
  --method GET \
  --url "https://graph.microsoft.com/v1.0/identity/conditionalAccess/policies" \
  --query "value[?contains(displayName, 'MFA')].{Name:displayName, State:state}"

# Note: Creating Conditional Access policies requires Microsoft Graph PowerShell
# Use the Entra admin center for GUI-based configuration

Bulk Remediation with PowerShell

# Remediate all storage accounts without secure transfer
$subscriptionId = (Get-AzContext).Subscription.Id
$storageAccounts = Get-AzStorageAccount | Where-Object { $_.EnableHttpsTrafficOnly -eq $false }

foreach ($sa in $storageAccounts) {
    Write-Host "Enabling secure transfer on $($sa.StorageAccountName)..."
    Set-AzStorageAccount -ResourceGroupName $sa.ResourceGroupName `
        -Name $sa.StorageAccountName `
        -EnableHttpsTrafficOnly $true
}

# Remediate all SQL servers without auditing
$sqlServers = Get-AzSqlServer

foreach ($server in $sqlServers) {
    $auditPolicy = Get-AzSqlServerAudit -ResourceGroupName $server.ResourceGroupName `
        -ServerName $server.ServerName

    if ($auditPolicy.BlobStorageTargetState -ne "Enabled") {
        Write-Host "Enabling auditing on $($server.ServerName)..."
        Set-AzSqlServerAudit -ResourceGroupName $server.ResourceGroupName `
            -ServerName $server.ServerName `
            -State Enabled `
            -StorageAccountName "stauditlogs"
    }
}

Step 5: Track Secure Score

View Score Impact

  1. In Defender for Cloud, click Secure Score
  2. Review score breakdown:
    • Overall score percentage
    • Points by security control
    • Score trend over time
  3. Click Regulatory compliance to see CIS-specific impact

Query Secure Score via CLI

# Get current Secure Score
az security secure-score list \
  --query "[].{Control:displayName, Current:score.current, Max:score.max, Percentage:score.percentage}" \
  -o table

# Get score by control
az security secure-score-controls list \
  --query "[].{Control:displayName, Current:score.current, Max:score.max, Unhealthy:unhealthyResourceCount}" \
  -o table | head -20

# Calculate improvement from CIS remediation
az security secure-score-controls show \
  --name "Remediate vulnerabilities" \
  --query '{Control:displayName, CurrentScore:score.current, MaxScore:score.max, PotentialGain:to_string(score.max - score.current)}'

Set Compliance Targets

# Export compliance baseline for tracking
az security regulatory-compliance-assessments list \
  --standard-name "CIS-Azure-2.0.0" \
  --control-name "1.1" \
  --query "[].{Assessment:name, State:state, SkippedResources:skippedResources}" \
  -o json > cis-baseline-$(date +%Y%m%d).json

# Create compliance report
az graph query -q "
  securityresources
  | where type == 'microsoft.security/regulatorycompliancestandards/regulatorycompliancecontrols'
  | where name startswith 'CIS'
  | extend standard = tostring(split(id, '/')[8])
  | extend control = tostring(properties.description)
  | extend state = tostring(properties.state)
  | project standard, control, state
" -o json > cis-compliance-report.json

Step 6: Generate Compliance Reports

Export from Portal

  1. In Regulatory compliance, select CIS benchmark
  2. Click Download report
  3. Choose format:
    • PDF for executive summary
    • CSV for detailed analysis

Generate Reports via PowerShell

# Generate CIS compliance report
$standards = Get-AzSecurityRegulatoryComplianceStandard

foreach ($standard in $standards | Where-Object { $_.Name -like "*CIS*" }) {
    $controls = Get-AzSecurityRegulatoryComplianceControl -StandardName $standard.Name

    $report = $controls | Select-Object @{
        Name = 'ControlId'
        Expression = { $_.Name }
    }, @{
        Name = 'Description'
        Expression = { $_.Description }
    }, @{
        Name = 'State'
        Expression = { $_.State }
    }, @{
        Name = 'PassedAssessments'
        Expression = { $_.PassedAssessments }
    }, @{
        Name = 'FailedAssessments'
        Expression = { $_.FailedAssessments }
    }

    $report | Export-Csv -Path "CIS-Compliance-$(Get-Date -Format 'yyyyMMdd').csv" -NoTypeInformation
}

Continuous Export to Log Analytics

# Configure continuous export for compliance data
WORKSPACE_ID=$(az monitor log-analytics workspace show \
  --resource-group "rg-security" \
  --workspace-name "law-security" \
  --query id -o tsv)

az security automation create \
  --name "export-compliance-data" \
  --resource-group "rg-security" \
  --scopes "/subscriptions/$SUBSCRIPTION_ID" \
  --sources '[{"eventSource": "RegulatoryComplianceAssessment"}]' \
  --actions "[{\"actionType\": \"LogAnalytics\", \"workspaceResourceId\": \"$WORKSPACE_ID\"}]"

Best Practices

  1. Prioritize Level 1 controls: Implement all L1 before L2
  2. Address high-impact first: Focus on controls affecting most resources
  3. Document exceptions: Use policy exemptions with justification
  4. Track trends: Monitor compliance percentage weekly
  5. Automate remediation: Use Azure Policy for continuous enforcement
  6. Review monthly: Reassess exemptions and new resources
  7. Integrate with ITSM: Create tickets for non-compliance
  8. Train teams: Ensure developers understand CIS requirements

Troubleshooting

Controls showing stale data:

  • Allow 4-24 hours for assessment refresh
  • Trigger manual evaluation: az security assessment
  • Verify resource is in scope of subscription

Remediation not reflecting in compliance:

  • Confirm remediation completed successfully
  • Check for dependent controls that also need remediation
  • Wait for next evaluation cycle (up to 24 hours)

Missing controls or assessments:

  • Verify Defender for Cloud is enabled
  • Check required Defender plans are active
  • Confirm resource types match control requirements

Exemptions not working:

  • Verify exemption scope matches resource
  • Check exemption expiration date
  • Confirm exemption category is appropriate

Next Steps

After implementing CIS compliance, enhance your security posture:

  • Enable additional standards (PCI DSS, HIPAA, SOC 2)
  • Implement Azure Policy for preventive controls
  • Configure Microsoft Sentinel for security monitoring
  • Review Cloud Security Tips for 2026 for comprehensive cloud security guidance

Frequently Asked Questions

Find answers to common questions

The CIS Azure Foundations Benchmark is a set of security configuration best practices published by the Center for Internet Security (CIS). It provides prescriptive guidance for establishing a secure baseline configuration for Azure environments. The benchmark covers identity, networking, logging, storage, databases, and other Azure services. Microsoft Defender for Cloud maps its recommendations to CIS controls for compliance assessment.

Azure Infrastructure Experts

Comprehensive Azure management including architecture, migration, security, and 24/7 operations.