From m365
Audits Microsoft 365 security posture including MFA enrollment, conditional access policies, risky sign-ins, suspicious inbox rules, and compromised account indicators. Essential for MSPs performing tenant security reviews or investigating account compromises.
How this skill is triggered — by the user, by Claude, or both
Slash command
/m365:securityWhen to use
When working with Microsoft 365 security posture checks - MFA enrollment status, conditional access policies, risky sign-ins, suspicious inbox rules. Use when: m365 security, m365 mfa, mfa enrollment, conditional access, risky sign-in, account compromise m365, m365 security audit, suspicious activity m365, m365 security score, entra security, or m365 sign-in logs.
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Security checks are among the most high-value tasks an MSP can perform in a customer's M365 tenant. Account compromises, inadequate MFA coverage, and misconfigured mail rules are the leading causes of M365 security incidents. This skill covers the key checks and indicators that separate a secure tenant from a vulnerable one.
Security checks are among the most high-value tasks an MSP can perform in a customer's M365 tenant. Account compromises, inadequate MFA coverage, and misconfigured mail rules are the leading causes of M365 security incidents. This skill covers the key checks and indicators that separate a secure tenant from a vulnerable one.
MFA enrollment lives on the authentication/methods endpoint per user. Users with only a passwordAuthenticationMethod entry have no MFA.
GET /v1.0/users/{userId}/authentication/methods
Response — user WITH MFA:
{
"value": [
{
"@odata.type": "#microsoft.graph.microsoftAuthenticatorAuthenticationMethod",
"id": "aad-method-id",
"displayName": "iPhone",
"createdDateTime": "2023-06-01T10:00:00Z"
},
{
"@odata.type": "#microsoft.graph.passwordAuthenticationMethod"
}
]
}
Response — user WITHOUT MFA (vulnerable):
{
"value": [
{
"@odata.type": "#microsoft.graph.passwordAuthenticationMethod"
}
]
}
Use Microsoft Graph Reports for tenant-wide MFA status:
GET /v1.0/reports/authenticationMethods/userRegistrationDetails
Response per user:
{
"id": "user-guid",
"userPrincipalName": "[email protected]",
"isMfaRegistered": true,
"isMfaCapable": true,
"isSsprRegistered": false,
"methodsRegistered": ["microsoftAuthenticator", "softwareOath"]
}
This is the fastest path to a full tenant MFA audit.
| Method | Security Level | Notes |
|---|---|---|
| FIDO2 hardware key | Highest | Phishing-resistant |
| Windows Hello for Business | Highest | Device-bound |
| Microsoft Authenticator (passwordless) | High | Number matching recommended |
| OATH hardware token | High | |
| Microsoft Authenticator (OTP) | Medium | Better than SMS |
| Software OATH (other app) | Medium | |
| SMS/Phone | Low | Susceptible to SIM swap |
| Password only | None | Unacceptable for business |
GET /v1.0/identityProtection/riskyUsers?$filter=riskState eq 'atRisk'&$select=id,userPrincipalName,riskLevel,riskState,riskLastUpdatedDateTime
Risk Levels: low, medium, high
GET /v1.0/auditLogs/signIns?$filter=riskLevelDuringSignIn ne 'none'&$select=userPrincipalName,riskLevelDuringSignIn,location,createdDateTime&$top=50
POST /v1.0/identityProtection/riskyUsers/dismiss
Content-Type: application/json
{
"userIds": ["user-guid"]
}
GET /v1.0/auditLogs/signIns?$filter=userPrincipalName eq '[email protected]'&$select=createdDateTime,userPrincipalName,ipAddress,location,status,clientAppUsed,riskLevelDuringSignIn&$top=20&$orderby=createdDateTime desc
Key fields for incident response:
status.errorCode: 0 = success, nonzero = failureipAddress and location for geolocation anomaliesclientAppUsed — legacy auth clients are high riskconditionalAccessStatus: notApplied = CA policy gapAttackers often create hidden inbox rules to forward mail or hide replies. Check for:
GET /v1.0/users/{userId}/mailFolders/inbox/messageRules
Red flags:
{
"displayName": "hidden rule",
"conditions": { "subjectContains": ["invoice"] },
"actions": { "forwardTo": [{ "emailAddress": { "address": "[email protected]" } }] },
"isEnabled": true
}
Legacy auth protocols (IMAP, POP3, SMTP AUTH, basic auth) bypass MFA. Identify users still using them:
GET /v1.0/auditLogs/signIns?$filter=clientAppUsed eq 'IMAP' or clientAppUsed eq 'POP3' or clientAppUsed eq 'Exchange ActiveSync'&$select=userPrincipalName,clientAppUsed,createdDateTime&$top=100
Recommended: Block legacy auth via Conditional Access policy.
Check if CA policies are configured:
GET /v1.0/identity/conditionalAccess/policies?$select=id,displayName,state,conditions,grantControls
state values: enabled, disabled, enabledForReportingButNotEnforced (report-only)
MSP baseline CA policies to verify exist:
Get the tenant's Microsoft Secure Score:
GET /v1.0/security/secureScores?$top=1
Response:
{
"value": [{
"currentScore": 52.4,
"maxScore": 120.0,
"averageComparativeScores": [
{ "basis": "AllTenants", "averageScore": 38.2 }
]
}]
}
Score improvement recommendations:
GET /v1.0/security/secureScoreControlProfiles?$select=title,maxScore,implementationStatus,controlCategory
When a user reports suspicious activity, check these in order:
| Check | Command | Red Flag |
|---|---|---|
| Recent sign-ins | GET /auditLogs/signIns | Unfamiliar IP, country, time |
| MFA changes | GET /auditLogs/directoryAudits | MFA method added/removed |
| Inbox rules | GET /mailFolders/inbox/messageRules | External forwarding |
| Sent items | GET /messages from Sent folder | Phishing sent from account |
| OAuth apps | GET /oauth2PermissionGrants | Unknown app granted access |
POST /v1.0/users/{id}/revokeSignInSessions| Task | Microsoft Graph Permission |
|---|---|
| MFA registration report | UserAuthenticationMethod.Read.All |
| Authentication methods | UserAuthenticationMethod.Read.All |
| Sign-in logs | AuditLog.Read.All |
| Risky users | IdentityRiskyUser.Read.All (P2) |
| Conditional access | Policy.Read.All |
| Security score | SecurityEvents.Read.All |
| Revoke sessions | Directory.ReadWrite.All |
npx claudepluginhub wyre-technology/msp-claude-plugins --plugin m365Audits Microsoft Entra identity and Conditional Access posture: enumerates CA policies, MFA coverage gaps, privileged role assignments, PIM configuration, risky sign-ins, and stale guest accounts. Proposes least-privilege hardening steps with blast-radius assessment and rollback plan.
Parses Office 365 Unified Audit Logs via Microsoft Graph API to detect account compromise indicators like forwarding rules, inbox delegation, and OAuth grants. For SOC incident investigations and threat hunting.
Parses Office 365 Unified Audit Logs via Microsoft Graph API to detect indicators of account compromise such as email forwarding, inbox delegation, and suspicious OAuth grants.