scoring-rules.json
|
{
"$schema": "https://json-schema.org/draft/2020-12/schema", "description": "M365 Security Assessment Score - Scoring Rules Configuration", "baseScore": 100, "rules": [ { "id": "sensitivity-labels", "name": "Missing Sensitivity Labels", "description": "Sites without information protection labels applied", "enabled": true, "maxPenalty": 15, "calculation": "percentage-based", "threshold": 50, "message": "Missing sensitivity labels on {percentage}% of sites: -{deduction} points", "notes": "Penalty scales from 0 to 15 points. Full penalty applied when >50% of sites are missing labels." }, { "id": "anonymous-sharing", "name": "Anonymous Sharing Enabled", "description": "Sites that allow anonymous access (anyone with link, no sign-in required)", "enabled": true, "maxPenalty": 20, "calculation": "flat", "threshold": 1, "message": "Sites with anonymous sharing enabled ({count}): -{deduction} points", "notes": "CRITICAL RISK: Full 20 point penalty if ANY site allows anonymous access.", "severity": "critical" }, { "id": "anonymous-links", "name": "Active Anonymous Sharing Links", "description": "Sites with active anonymous sharing links created", "enabled": true, "maxPenalty": 15, "calculation": "flat", "threshold": 1, "message": "Sites with active anonymous links ({count}): -{deduction} points", "notes": "CRITICAL RISK: Full 15 point penalty if ANY site has active anonymous links.", "severity": "critical" }, { "id": "external-users", "name": "External Users (Guests)", "description": "Sites with external users who have been granted access", "enabled": true, "maxPenalty": 15, "calculation": "prevalence-based", "threshold": 100, "message": "Sites with external users ({count}): -{deduction} points", "notes": "Penalty scales based on how many sites with external sharing actually have guest users. 100% prevalence = full penalty.", "severity": "high" }, { "id": "adhoc-permissions", "name": "Ad-Hoc Permissions", "description": "Sites where users have direct permissions (not via SharePoint groups)", "enabled": true, "maxPenalty": 10, "calculation": "percentage-based", "threshold": 20, "message": "Sites with ad-hoc permissions ({count}): -{deduction} points", "notes": "Penalty scales from 0 to 10 points. Full penalty when >20% of sites have ad-hoc permissions.", "severity": "medium" }, { "id": "external-access-prevalence", "name": "High External Access Prevalence", "description": "Too many sites have external sharing enabled", "enabled": true, "maxPenalty": 10, "calculation": "percentage-above-threshold", "threshold": 75, "message": "High external access prevalence ({percentage}%): -{deduction} points", "notes": "Penalty starts at 75% threshold. Full penalty when 100% of sites have external access enabled.", "severity": "medium" }, { "id": "disabled-users-licenses", "name": "Disabled Users with Licenses", "description": "Inactive users still consuming paid licenses (cost optimization)", "enabled": true, "maxPenalty": 10, "calculation": "percentage-based", "threshold": 50, "message": "Disabled users with licenses ({count}): -{deduction} points", "notes": "Penalty scales from 0 to 10 points. Full penalty when >50% of disabled users still have licenses.", "severity": "low" }, { "id": "app-secrets-expiring", "name": "App Registrations with Expired/Expiring Secrets", "description": "Applications that have expired secrets or secrets expiring in the next 30 days", "enabled": true, "maxPenalty": 15, "calculation": "flat", "threshold": 1, "message": "Apps with expired or soon-to-expire secrets ({count}): -{deduction} points", "notes": "SECURITY RISK: Full penalty if any app has an expired secret or a secret expiring within 30 days.", "severity": "high" }, { "id": "unused-app-registrations", "name": "Unused App Registrations", "description": "Applications with no sign-in activity in the last 30 days (for apps where usage data is available)", "enabled": true, "maxPenalty": 10, "calculation": "flat", "threshold": 1, "message": "Unused app registrations ({count}): -{deduction} points", "notes": "Security hygiene risk: stale app registrations should be reviewed or removed.", "severity": "medium" }, { "id": "sensitive-app-registrations", "name": "Sensitive App Registrations", "description": "Applications with elevated, write-capable, or privilege-granting permissions", "enabled": true, "maxPenalty": 15, "calculation": "flat", "threshold": 1, "message": "Sensitive app registrations ({count}): -{deduction} points", "notes": "Apps are marked sensitive by privileged-permission detection patterns in this file.", "severity": "high" }, { "id": "group-owner-governance", "name": "Group Owner Governance Violations", "description": "Groups with owner count outside allowed range or group principals as owners", "enabled": true, "maxPenalty": 10, "calculation": "flat", "threshold": 1, "message": "Group owner governance violations ({count}): -{deduction} points", "notes": "Applies when owner count is below minOwners or above maxOwners, or owner is a group when flagGroupOwners=true.", "severity": "medium" }, { "id": "site-owner-governance", "name": "Site Owner Governance Violations", "description": "Sites with owner/admin count outside allowed range or group principals with full control", "enabled": true, "maxPenalty": 15, "calculation": "flat", "threshold": 1, "message": "Site owner governance violations ({count}): -{deduction} points", "notes": "For group-connected sites, group owner metrics are reused.", "severity": "high" } ], "ownerGovernance": { "enabled": true, "minOwners": 2, "maxOwners": 5, "flagGroupOwners": true }, "privilegedPermissionDetection": { "enabled": true, "minPrivilegedPermissionCount": 3, "excludePermissionPatterns": [ "^openid$", "^profile$", "^email$", "^offline_access$", "^User\\.Read$" ], "alwaysSensitivePermissionPatterns": [ "^Directory\\.AccessAsUser\\.All$", "^AppRoleAssignment\\.ReadWrite\\.All$", "^DelegatedPermissionGrant\\.ReadWrite\\.All$", "^RoleManagement\\.ReadWrite\\..*$", "^RoleAssignmentSchedule\\.ReadWrite\\..*$", "^RoleEligibilitySchedule\\.ReadWrite\\..*$", "^Application\\.ReadWrite\\..*$", "^Directory\\.ReadWrite\\.All$", "^Sites\\.FullControl\\.All$", "^Sites\\.Manage\\.All$", "^Exchange\\.ManageAsApp$", "^GroupMember\\.ReadWrite\\.All$", "^Group\\.ReadWrite\\.All$", "^User\\.ReadWrite\\.All$", "^RoleManagement\\.ReadWrite\\.Directory$" ], "privilegedPermissionPatterns": [ "\\b(ReadWrite|Write|Manage|FullControl|Delete|Create|Update|Send|AccessAsUser|PrivilegedOperations|ReadWrite\\.All|ReadWrite\\.OwnedBy)\\b", "^(RoleManagement|RoleAssignmentSchedule|RoleEligibilitySchedule|Policy\\.ReadWrite|AppRoleAssignment\\.ReadWrite|DelegatedPermissionGrant\\.ReadWrite|Directory\\.ReadWrite|Application\\.ReadWrite|Sites\\.(Manage|FullControl)|GroupMember\\.ReadWrite|Group\\.ReadWrite|User\\.ReadWrite).*" ] }, "grades": [ { "grade": "Excellent", "minScore": 90, "maxScore": 100, "color": "green", "description": "Strong security posture with minimal risks" }, { "grade": "Good", "minScore": 80, "maxScore": 89, "color": "green", "description": "Good security with minor improvements recommended" }, { "grade": "Fair", "minScore": 70, "maxScore": 79, "color": "yellow", "description": "Address identified security concerns" }, { "grade": "Poor", "minScore": 60, "maxScore": 69, "color": "yellow", "description": "Significant security risks present" }, { "grade": "Critical", "minScore": 0, "maxScore": 59, "color": "red", "description": "Immediate remediation required" } ], "exclusions": { "description": "Sites to exclude from all analyses", "patterns": [ "*-my.sharepoint.com/personal/*", "*/search" ], "notes": "OneDrive sites and the search center are excluded from site counts and scoring." }, "calculationMethods": { "flat": "Fixed penalty if threshold is met (count >= threshold)", "percentage-based": "Penalty scales linearly from 0 to maxPenalty based on percentage (100% = maxPenalty when percentage >= threshold)", "prevalence-based": "Penalty scales based on prevalence among a subset (e.g., external users among external-enabled sites)", "percentage-above-threshold": "Penalty only applies above threshold, scales from threshold to 100%" } } |