Summary
This workflow performs a targeted audit of Microsoft 365 Conditional Access policies, evaluating their configuration against security best practices and organizational requirements. The solution examines all active, disabled, and report-only policies, identifies gaps in coverage, detects misconfigurations, validates MFA enforcement, checks for legacy authentication blocks, and assesses device compliance requirements. The audit generates a comprehensive report with a security score, detailed findings, and actionable remediation recommendations to strengthen the organization's identity security posture.
Usage
Prerequisites
Before using this workflow, ensure the following requirements are met:
-
Microsoft Graph API Integration: Configure with the following permissions:
Policy.Read.All- To read conditional access policiesDirectory.Read.All- To read directory dataUser.Read.All- To read user and group membershipsApplication.Read.All- To read application registrations
-
Organizational Variables:
ca_audit_baseline: Security baseline to audit against (CIS,NIST,Custom)ca_audit_report_recipients: Email addresses for report distributionca_audit_alert_on_critical: Send immediate alerts for critical findingsca_required_policies: List of policies that must exist
Workflow Inputs
| Parameter | Type | Required | Description |
|---|---|---|---|
tenant_id | String | No | Specific tenant to audit |
include_disabled_policies | Boolean | No | Include disabled policies in audit. Default: true |
include_report_only | Boolean | No | Include report-only policies. Default: true |
security_baseline | String | No | Framework to audit against. Default: CIS |
compare_to_previous | Boolean | No | Compare to last audit. Default: true |
send_report | Boolean | No | Email report to recipients. Default: true |
Execution
Scheduled Execution (Recommended)
- Run weekly or monthly as part of security compliance program
- Schedule before compliance reviews
Event-Driven Trigger
- Trigger when conditional access policy changes are detected
- Run after admin role changes
Audit Process Flow
- Policy Enumeration: Retrieve all conditional access policies
- Policy Analysis: Evaluate each policy configuration and scope
- Gap Detection: Identify missing recommended policies
- MFA Coverage: Validate MFA enforcement across user populations
- Legacy Auth Check: Verify legacy authentication is blocked
- Device Compliance: Assess device-based access requirements
- Location Policies: Review named locations and geo-blocking
- Application Coverage: Check application-specific policies
- Admin Protection: Verify privileged role protections
- Report Generation: Create detailed audit report with scoring
- Comparison: Compare findings to previous audit results
- Notification: Distribute report to stakeholders
Returned Data
{
"success": true,
"audit_summary": {
"security_score": 68,
"score_change": -5,
"total_policies": 12,
"active_policies": 8,
"disabled_policies": 2,
"report_only_policies": 2,
"critical_findings": 2,
"high_findings": 4,
"medium_findings": 6,
"low_findings": 3
},
"required_policies_status": {
"block_legacy_auth": { "exists": true, "enabled": true, "compliant": true },
"require_mfa_all_users": { "exists": true, "enabled": true, "compliant": true },
"require_mfa_admins": { "exists": true, "enabled": true, "compliant": true },
"block_untrusted_locations": { "exists": false, "enabled": false, "compliant": false },
"require_compliant_devices": { "exists": true, "enabled": false, "compliant": false },
"require_approved_apps": { "exists": false, "enabled": false, "compliant": false }
},
"critical_findings": [
{
"finding": "No policy blocks access from untrusted locations",
"risk": "Attackers can authenticate from any geographic location",
"remediation": "Create a conditional access policy with named locations to block high-risk countries"
},
{
"finding": "Device compliance policy is disabled",
"risk": "Unmanaged and non-compliant devices can access corporate resources",
"remediation": "Enable the existing device compliance conditional access policy"
}
],
"mfa_coverage": {
"users_covered_by_mfa_policy": 420,
"users_not_covered": 30,
"admin_accounts_with_mfa_policy": 11,
"admin_accounts_without_mfa_policy": 1,
"coverage_percentage": 93.3
},
"policy_details": [
{
"policy_name": "Require MFA for All Users",
"state": "enabled",
"users_targeted": "All Users",
"exclusions": ["Emergency Access Account"],
"grant_controls": ["MFA"],
"applications": "All Applications",
"conditions": {},
"assessment": "Compliant"
}
]
}
Changelog
2026-03-04
- Initial version of the document