# yaml-language-server: $schema=https://github.com/benedictjohannes/crobe/releases/latest/download/playbook.schema.json title: "Lixus Desktop Compliance Report (MacOS)" reportFrontmatter: author: "SRE Team" sections: - title: "1. OS Maintenance & Security" description: - "Checks for OS updates, official verification, and authentication security." assertions: - code: OS_RECENTLY_UPDATED title: "OS Recently Updated" description: "Verify the system has been updated within the last 30 days." cmds: - exec: script: | # Get the last update time from SystemVersion.plist modification date last_update=$(stat -f %m /System/Library/CoreServices/SystemVersion.plist 2>/dev/null) if [ -n "$last_update" ]; then echo "$last_update" else echo "Unknown" fi gather: - key: "OS_LAST_UPDATE_TIME" func: | (stdout) => { const val = parseInt(stdout.trim()); return isNaN(val) ? "Unknown" : new Date(val * 1000).toISOString(); } stdOutRule: func: | (stdout, stderr) => { const lastUpdate = parseInt(stdout.trim()); if (isNaN(lastUpdate)) return -1; const thirtyDaysInSeconds = 30 * 24 * 60 * 60; const nowInSeconds = Math.floor(Date.now() / 1000); return (nowInSeconds - lastUpdate) < thirtyDaysInSeconds ? 1 : -1; } passDescription: "System was updated in the last 30 days." failDescription: "System has not been updated in the last 30 days." - code: OS_INTEGRITY title: "OS Integrity Verification" description: "Checks if the OS is recognized from official sources." cmds: - exec: script: "sw_vers -productName" stdOutRule: regex: "macOS" passDescription: "OS is identified as a recognized distribution." failDescription: "OS distribution is not recognized or is non-standard." - code: DEVICE_INFO title: "Device Identification" description: "Gathering hardware identities (Brand, Model, and Serial)." cmds: - exec: func: | ({ os }) => ` MODEL=$(sysctl -n hw.model) SERIAL=$(system_profiler SPHardwareDataType | awk '/Serial Number/ {print $NF}') echo "${ os === 'mac' ? 'Apple' : 'Unknown' }|||$MODEL|||$SERIAL" ` gather: - key: "DEVICE_BRAND" func: "(stdout) => stdout.split('|||')[0]" - key: "DEVICE_MODEL" func: "(stdout) => stdout.split('|||')[1]" - key: "DEVICE_SERIAL" func: "(stdout) => stdout.split('|||')[2].trim()" stdOutRule: func: (stdout) => stdout.split('|||').length === 3 passDescription: Device information successfully gathered failDescription: Fail to gather device information - title: "2. Identity & Access Control" description: - "Audits login configurations, screen lock, and administrative privileges." assertions: - code: NO_AUTO_LOGIN title: "No Auto Login" description: "Ensures automatic login is disabled." cmds: - exec: script: "if [ -f /etc/kcpassword ]; then echo 'Enabled'; else echo 'None'; fi" stdOutRule: regex: "None" passDescription: "Auto login is disabled." failDescription: "Auto login appears to be enabled in system preferences." - code: SCREEN_LOCK_TIMEOUT title: "Screen Lock Timeout" description: "Verify screen lock timeout is under 30 minutes (1800 seconds)." cmds: - exec: script: | idle=$(defaults -currentHost read com.apple.screensaver idleTime 2>/dev/null || echo 0) display_sleep=$(pmset -g custom | awk '/displaysleep/ {print $2}' | sort -n | tail -n 1) display_sleep_sec=$((display_sleep * 60)) if [ "$idle" -eq 0 ] && [ "$display_sleep_sec" -eq 0 ]; then echo 0 elif [ "$idle" -eq 0 ]; then echo "$display_sleep_sec" elif [ "$display_sleep_sec" -eq 0 ]; then echo "$idle" elif [ "$idle" -lt "$display_sleep_sec" ]; then echo "$idle" else echo "$display_sleep_sec" fi gather: - key: "SCREEN_LOCK_TIMEOUT_SECONDS" func: | (stdout) => { const val = stdout.trim(); return isNaN(parseInt(val)) ? "Unknown" : val; } stdOutRule: func: | (stdout) => { const timeout = parseInt(stdout.trim()); if (timeout === 0) return -1; return timeout <= 1800 ? 1 : -1; } passDescription: "Screen lock timeout is configured within safe limits." failDescription: "Screen lock timeout is too long or disabled." - code: USER_PRIVILEGE title: "User is not running as local administrator" description: "Ensures the current user is not local administrator/root." cmds: - exec: script: "id -u" gather: - key: "CURRENT_USER_ID" func: "(stdout) => stdout.trim()" stdOutRule: # Current user should not be root (0) regex: "^[1-9][0-9]*$" passDescription: "User is operating with standard privileges." failDescription: "User is operating with administrative privileges." - title: "3. Disk Security" description: - "Checks for disk encryption status." assertions: - code: ENCRYPTION_STATUS title: "Disk / Storage is Encrypted" description: "Verify that at least one block device is encrypted." cmds: - exec: script: "fdesetup status" gather: - key: "ENCRYPTED_DEVICES" func: "(stdout) => stdout.includes('FileVault is On') ? 'Main Disk (FileVault)' : 'None'" stdOutRule: regex: "FileVault is On" passDescription: "Encrypted volumes detected." failDescription: "No encrypted volumes found." - title: "4. Threat and Malware Protection" description: - "Checks for Antivirus installation, update status, and real-time protection." assertions: - code: ANTIVIRUS_ACTIVE title: "Antivirus Active" description: "Verify that antivirus is running." cmds: - exec: script: | GK=$(spctl --status | grep -o "enabled") SIP=$(csrutil status | grep -o "enabled") echo "Gatekeeper: $GK, SIP: $SIP" stdOutRule: regex: "Gatekeeper: enabled, SIP: enabled" passDescription: "System protection services are active" failDescription: "One or more system protection services are disabled." - code: ANTIVIRUS_UPDATED title: "Antivirus Definitions Up-to-Date" description: "Check if antivirus definitions were updated in the last 30 days." cmds: - exec: script: "stat -f %m /Library/Apple/System/Library/CoreServices/XProtect.bundle/Contents/Resources/XProtect.yara 2>/dev/null || echo 'Unknown'" gather: - key: "ANTIVIRUS_LAST_UPDATE" func: | (stdout) => { const val = parseInt(stdout.trim()); return isNaN(val) ? "Unknown" : new Date(val * 1000).toISOString(); } stdOutRule: func: | (stdout) => { const stamp = parseInt(stdout.trim()); if (isNaN(stamp)) return -1; const thirtyDays = 30 * 24 * 60 * 60; const now = Math.floor(Date.now() / 1000); return (now - stamp) < thirtyDays ? 1 : -1; } passDescription: "Definitions are up to date." failDescription: "Definitions are older than 30 days or missing." - title: "5. Network Security" description: - "Checks firewall and network protection status." assertions: - code: FIREWALL_ACTIVE title: "Firewall Status" description: "Verify that a firewall is active." cmds: - exec: script: "/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate" gather: - key: "FIREWALL_STATUS" func: "(stdout) => stdout.trim()" stdOutRule: regex: "Firewall is enabled" passDescription: "Firewall is active." failDescription: "No active firewall detected." - title: "6. Boot Security" description: - "Verification of firmware security settings." assertions: - code: SECURE_BOOT_ENABLED title: "Secure Boot State" description: "Check if UEFI Secure Boot is enabled." cmds: - exec: script: "system_profiler SPiBridgeDataType SPSoftwareDataType 2>/dev/null | grep 'Secure Boot' | awk -F':' '{print $2}' | xargs" stdOutRule: regex: "(Full Security|Medium Security)" passDescription: "Secure Boot is enabled." failDescription: "Secure Boot is disabled or set to No Security." - title: "7. Application Integrity" description: - "Audits browser update status." assertions: - code: BROWSER_UP_TO_DATE title: "Browser Updated" description: "Verify if the primary web browsers has been updated within the last 30 days." cmds: - exec: script: | for b in /Applications/Safari.app /Applications/Google\ Chrome.app /Applications/Firefox.app; do if [ -d "$b" ]; then echo "$b:$(stat -f %m "$b")" fi done gather: - key: "SAFARI_LAST_UPDATE" func: | (stdout) => { const line = stdout.trim().split('\n').find(l => l.includes('Safari')); if (!line) return "Not Installed"; return new Date(parseInt(line.split(':')[1]) * 1000).toISOString(); } - key: "FIREFOX_LAST_UPDATE" func: | (stdout) => { const line = stdout.trim().split('\n').find(l => l.includes('Firefox')); if (!line) return "Not Installed"; return new Date(parseInt(line.split(':')[1]) * 1000).toISOString(); } - key: "CHROME_LAST_UPDATE" func: | (stdout) => { const line = stdout.trim().split('\n').find(l => l.includes('Chrome')); if (!line) return "Not Installed"; return new Date(parseInt(line.split(':')[1]) * 1000).toISOString(); } stdOutRule: func: | (stdout) => { const lines = stdout.trim().split('\n').filter(Boolean); let latest = 0; lines.forEach(line => { const stamp = parseInt(line.split(':')[1]); if (stamp > latest) latest = stamp; }); if (latest === 0) return -1; const thirtyDays = 30 * 24 * 60 * 60; const now = Date.now() / 1000; return (now - latest) < thirtyDays ? 1 : -1; } passDescription: "At least one browser appears recently updated." failDescription: "No recently updated browsers found." - title: "8. Monitoring & Logging" description: - "Ensures system event logging is active." assertions: - code: LOGGING_ACTIVE title: "System has active logging service" description: "Verify that system logging service is active." cmds: - exec: script: "log show --last 1m >/dev/null 2>&1 && echo 'active' || echo 'inactive'" stdOutRule: regex: "active" passDescription: "System logging is active." failDescription: "System logging service is not running."