Maintaining visibility into Conditional Access Policy changes in Microsoft Entra ID (formerly Azure AD) can be challenging. Whether tracking down who made a specific change, understanding what was modified, or maintaining documentation of policy evolution.
ConditionalAccessIQ streamlines this process by providing automatic version control, change tracking, and visual comparisons of your Conditional Access Policies. The tool enables administrators to continuously monitor for changes, maintains a detailed history of changes, and generates clear, interactive reports showing exactly what was modified, when, and by whom.
- Alpha Version: This is a work in progress, while I have deployed this in to production environments, there may be some bugs and issues. Your feedback is important to me, please share any issues you find. The code was developed in a way to be able to dynamically adjust to new conditional access policies features that are released, however, that may not always be the case.
Every policy change is documented with an interactive HTML report that shows:
- Side-by-side comparisons of policy changes
- Complete audit information including who made changes
- Automatic JSON backups of each version
- Audit log id that contains the full audit log entry
- Modified, Created, and Deleted by wnd time
Version: 0.0.3
Author: Gabriel Delaney (GitHub)
Company: Phoenix Horizons LLC
- Features
- Prerequisites
- Installation
- Authentication Setup
- Usage Guide
- Sample Output
- Known Limitations
-
π Version Control
- Policy version history
- Automatic JSON backups
- Change comparison
- Audit trail tracking
-
π Change Visualization
- Interactive HTML report
- Before/after comparisons
- Timeline tracking
- Identity resolution
-
π Detailed Analysis
- Property-level changes
- User tracking
- Application mapping
- Role resolution
-
π¨ Reporting Options
- HTML reports
- Email notifications
- JSON exports
- Audit archiving
- PowerShell 5.1 or PowerShell 7.x
- Microsoft.Graph.Authentication module (automatically installed)
- Policy.Read.All
- AuditLog.Read.All
- Directory.Read.All
- Application.Read.All
- Mail.Send (only if using email functionality)
When using delegated permissions (as opposed to application permissions), you need:
- Global Reader: This role provides all necessary permissions for the tool to function
# Install from PowerShell Gallery
Install-Module -Name ConditionalAccessIQ -Scope CurrentUser
# Import the module
Import-Module ConditionalAccessIQ
# Connect with required scopes
Connect-MgGraph -Scopes @(
"Policy.Read.All",
"AuditLog.Read.All",
"Directory.Read.All",
"Application.Read.All"
)
-
Navigate to Entra Portal > App Registrations
-
Create New Registration:
-
Add Required Permissions:
- Click "API Permissions"
- Add Microsoft Graph permissions:
- Policy.Read.All (Application)
- AuditLog.Read.All (Application)
- Directory.Read.All (Application)
- Application.Read.All (Application)
- Mail.Send (Application, if using email - see note below)
- Grant admin consent
Note on Mail.Send Permission: When configuring Mail.Send, you should specify which mailbox the application can access. See Microsoft's guidance on limiting mailbox access for configuration details.
-
Create Secret or Certificate:
- Under "Certificates & secrets"
- Create new client secret or upload certificate
- Save credentials securely
-
Connect Using App Credentials:
# Using client secret
$client_id = "your-client-id"
$client_secret = "your-client-secret" | ConvertTo-SecureString -AsPlainText -Force
$client_secret_credential = New-Object System.Management.Automation.PSCredential($client_id, $client_secret)
$tenant_id = "your-tenant-id"
Connect-MgGraph -ClientSecretCredential $client_secret_credential -TenantId $tenant_id
# Or using certificate
Connect-MgGraph -ClientId $client_id -CertificateThumbprint "cert-thumbprint" -TenantId $tenant_id
Monitor and track Conditional Access policy changes:
# Monitor changes for last 24 hours (default)
Invoke-CAIQ
# Monitor changes for specific date range
$start_date = (Get-Date).AddDays(-7).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
$end_date = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
Invoke-CAIQ -StartDate $start_date -EndDate $end_date
# Custom output path
Invoke-CAIQ -OutputPath "C:\CAIQReports"
# Custom report name
Invoke-CAIQ -FileName "CA_Changes_Report.html"
# Generate without opening browser
Invoke-CAIQ -InvokeHtml:$false
Send email notifications about policy changes:
Send-CAIQMailMessage -To "jdoe@contoso.com" -From "thetolkienblackguy@contoso.com" -Subject "Daily CA Changes Report" -Subject "CA Policy Changes" -Body "Please review the attached report." -Attachments "$($PWD)\ConditionalAccessIQ\CA_Changes_Report.html"
Since Conditional Access changes are critical to security, it's recommended to automate this tool to run daily. Here's an example PowerShell script you could schedule:
# Install and import if needed
Import-Module ConditionalAccessIQ
# Connect using certificate auth (recommended for automation)
Connect-MgGraph -ClientId $client_id -CertificateThumbprint "cert-thumbprint" -TenantId $tenant_id
# Run report for last 24 hours
Invoke-CAIQ -InvokeHtml:$false
# The report path
$html_path = "$($PWD)\ConditionalAccessIQ\Conditional_Access_Intelligence.html"
# If the report exists get the content of it, if not, exit.
If ((Test-Path $html_path -PathType Leaf)) {
$html = Get-Content -Path $html_path -Raw
} Else {
Exit
}
# Email the report
Send-CAIQMailMessage -To "jdoe@contoso.com" -From "thetolkienblackguy@contoso.com" -Subject "Daily CA Changes Report" -Body $html -Attachments $html_path
You can schedule this script using:
- Windows Task Scheduler
- Azure Automation
The tool provides several output formats:
- Policy change timeline
- Visual before/after comparisons
- Change highlighting
- User and identity resolution
- Version tracking
- Automatic version backups
- Full policy configurations
- Restoration capability
- Historical documentation
- Interactive timelines
- Searchable changes
- Detailed audit information
- Email-ready format
- Complete change history
- User activity tracking
- Modification timestamps
- Service principal recording
Audit Log Access
- Limited to 30-day history
- Regular monitoring recommended for complete history
This project is licensed under the MIT License.