Assess Microsoft 365 Security with cnspec
Use cnspec to assess Microsoft 365 for security misconfigurations
Rely on cnspec to ensure your Microsoft 365 environment follows security best practices, such as verifying security defaults, controlling third-party application access, auditing authorization policies, and reviewing conditional access rules across your tenant.
Before you begin
To test your Microsoft 365 environment with cnspec, you must have:
Give cnspec access
cnspec relies on the Microsoft Graph API. To give cnspec permission to access your data, you must create a registered app in Azure. To learn how, read Secure Microsoft 365 with Mondoo.
In all commands, if you have a secret key but not a certificate, you can provide --client-secret 'SECRET' instead of --certificate-path.
Use environment variables for credentials
Instead of passing credentials on every command, you can set environment variables:
On Linux / macOS:
export AZURE_TENANT_ID=YOUR-TENANT-ID
export AZURE_CLIENT_ID=YOUR-CLIENT-ID
export AZURE_CLIENT_SECRET='YOUR-SECRET'On Windows, using PowerShell:
$Env:AZURE_TENANT_ID = "YOUR-TENANT-ID"
$Env:AZURE_CLIENT_ID = "YOUR-CLIENT-ID"
$Env:AZURE_CLIENT_SECRET = "YOUR-SECRET"When these variables are set, you can omit the corresponding flags from all the commands below.
Test your connection
Before running a full scan, verify that your credentials work by opening a cnspec shell:
cnspec shell ms365 --certificate-path certificate.combo.pem --tenant-id YOUR-TENANT-ID --client-id YOUR-CLIENT-IDcnspec> microsoft.tenant.name
microsoft.tenant.name: "your-tenant-name"If you see your tenant name, cnspec is connected and ready to scan. You can also use help ms365 and help microsoft to explore available resources.
Scan Microsoft 365
To scan using the default policies:
cnspec scan ms365 --certificate-path certificate.combo.pem --tenant-id YOUR-TENANT-ID --client-id YOUR-CLIENT-IDUnderstand scan output
When a scan completes, cnspec prints a summary of all the checks it ran, grouped by policy. Each check shows a pass or fail result. For example:
✓ Pass: Ensure security defaults are appropriately managed
✕ Fail: Ensure third-party applications cannot connect to services
✓ Pass: Ensure all domains are verifiedAt the end of the output, cnspec shows a risk score from 0 (no risk) to 100 (highest risk). Failed checks include remediation guidance to help you fix issues.
Scan with the Mondoo Microsoft 365 Security policy
Mondoo maintains an out of the box Microsoft 365 Security policy that checks security defaults, authorization policies, conditional access, Exchange Online settings, and more.
Mondoo Platform users: Enable the policy in your space. In the Mondoo Console, go to Findings > Policies, search for "Microsoft 365", and add the policy. All future scans of your Microsoft 365 tenant automatically evaluate against it. To learn more, read Manage Policies.
Open source users: Pass the policy bundle URL directly to cnspec:
cnspec scan ms365 --certificate-path certificate.combo.pem --tenant-id YOUR-TENANT-ID --client-id YOUR-CLIENT-ID \
--policy-bundle https://raw.githubusercontent.com/mondoohq/cnspec/refs/heads/main/content/mondoo-m365-security.mql.yamlYou can also create your own policies to meet your specific requirements.
Explore your Microsoft 365 environment
Run cnspec shell ms365 (with the required flags above) to open the interactive shell. Use help ms365 or help microsoft to discover available resources.
List domains
cnspec> microsoft.domainsRetrieve domain details
cnspec> microsoft.domains { id passwordValidityPeriodInDays isAdminManaged }Filter domains
For example, find domains with expiring passwords:
cnspec> microsoft.domains.where(passwordValidityPeriodInDays != 2147483647) { id availabilityStatus }Get full details for all domains
cnspec> microsoft.domains { * }Example security checks
Ensure security defaults are disabled
When conditional access policies are in place, security defaults should be disabled to avoid conflicts:
cnspec> microsoft.policies.identitySecurityDefaultsEnforcementPolicy["isEnabled"] == false
[ok] value: falseEnsure third-party apps can't connect to your services
cnspec> microsoft.policies.authorizationPolicy {
_['defaultUserRolePermissions']['allowedToCreateApps'] == false
}
[ok] value: falseEnsure all domains are verified
cnspec> microsoft.domains { id isVerified == true }
[ok] value: trueEnsure MFA is enabled for all users
cnspec> microsoft.users { userPrincipalName mfaEnabled == true }Ensure on-premises sync is properly configured
cnspec> microsoft.tenant.onPremisesSyncEnabledContinuously scan your fleet
To move beyond one-off scans, set up a Microsoft 365 integration in Mondoo Platform. You get continuous monitoring across your Microsoft 365 tenant, a dashboard to track security posture over time, and integration with ticketing systems to manage remediation.
Learn more
-
To learn more about how the MQL query language works, read Write Effective MQL.
-
For a list of all the Microsoft 365 resources and fields you can query, read the Mondoo Microsoft 365 (M365) Resource Pack Reference.