A Bash-based security audit and hardening script for macOS, aligned with the CIS (Centre for Internet Security) Apple macOS Benchmark. Deployable standalone or fleet-wide via Jamf Pro. Built as a portfolio project to demonstrate security operations and compliance expertise.
- The Problem
- The Solution
- What Is the CIS Benchmark
- Controls Audited
- Prerequisites
- Repository Structure
- Installation & Usage
- Sample Output
- Deploying via Jamf Pro
- Important Notes on macOS Compatibility
- Skills Demonstrated
Enterprise IT teams managing macOS fleets face a consistent compliance challenge: devices drift from their secure baseline over time. Software gets installed, settings get changed, and sharing services get enabled — often without IT's knowledge.
Without a regular, automated audit:
- FileVault gets disabled after an OS update goes wrong — no one notices until an audit
- A developer enables SSH or Screen Sharing for a one-off task and never turns it off
- Guest accounts remain active on devices shipped to remote employees
- System Integrity Protection is disabled by a user following a YouTube tutorial
- Automatic security updates are turned off to avoid interruptions during a busy project
Each of these represents a real, exploitable gap in the organisation's security posture — and none of them generate alerts unless you are actively checking.
A single Bash script that audits 12 CIS Benchmark-aligned security controls on any macOS device, outputs a structured compliance report, and optionally applies safe remediations via a --fix flag.
Designed to run as a Jamf Pro policy on a daily or weekly schedule, it provides continuous compliance monitoring across the entire macOS fleet — without requiring any third-party security tooling.
Outcome (simulated):
- Security configuration drift detected automatically before it creates risk
- Compliance status visible per device in Jamf Pro policy logs
- Smart Groups dynamically group non-compliant devices for targeted remediation
- Audit trail written to
/var/log/cis_audit.logon every device
The CIS (Centre for Internet Security) Benchmark is a globally recognised set of security configuration guidelines developed by a community of cybersecurity professionals. It is widely used as the baseline for enterprise endpoint compliance in industries including finance, healthcare, and technology.
CIS Benchmarks define two profile levels:
| Level | Description |
|---|---|
| Level 1 | Essential security settings with minimal impact on usability. Recommended for all environments. |
| Level 2 | Enhanced security for higher-risk environments. May impact some workflows. |
This script focuses on Level 1 controls — the baseline that every managed macOS device should meet.
| # | Control | Category | Auto-Remediable |
|---|---|---|---|
| 1 | Software Update configuration | Patching | ✅ Yes (with --fix) |
| 2 | Bluetooth status | Network | |
| 3 | Remote Services (SSH, Screen Sharing, Remote Apple Events, ARD) | Remote Access | ✅ Partial |
| 4 | Sharing Services (File, Printer, Internet Sharing) | Sharing | ✅ Yes (with --fix) |
| 5 | Gatekeeper status | Application Control | ✅ Yes (with --fix) |
| 6 | FileVault encryption | Encryption | 🔧 Manual via Jamf profile |
| 7 | Application Firewall and Stealth Mode | Network | ✅ Yes (with --fix) |
| 8 | System Integrity Protection (SIP) | System | 🔧 Recovery Mode only |
| 9 | Screen lock idle timeout | Access Control | ✅ Yes (with --fix) |
| 10 | Security audit daemon (auditd) | Logging | ✅ Yes (with --fix) |
| 11 | Home folder permissions | Access Control | ✅ Yes (with --fix) |
| 12 | Guest account status | Access Control | ✅ Yes (with --fix) |
- macOS 12 (Monterey) or later
- Root privileges (
sudo) or Jamf Pro policy execution context - No external dependencies — uses only native macOS tools
macos-cis-benchmark-hardening/
├── macos_cis_hardening.sh # Main audit and hardening script
├── cis_controls_reference.md # CIS control category reference
├── remediation_guide.md # Remediation steps for each failing control
└── README.md # This file
git clone https://github.com/akshaymahaldar/macos-cis-benchmark-hardening.git
cd macos-cis-benchmark-hardening
chmod +x macos_cis_hardening.shsudo ./macos_cis_hardening.shsudo ./macos_cis_hardening.sh --fixcat /var/log/cis_audit.log======================================================================
macOS CIS BENCHMARK SECURITY AUDIT
Host: macbook-pro-akshay
macOS: 14.4.1
Mode: AUDIT ONLY (pass --fix to remediate)
Started: 2025-04-28 10:00:00
======================================================================
▶ CONTROL 1 — SOFTWARE UPDATES
─────────────────────────────────────────────────────
[PASS] Automatic update checks are enabled
[PASS] Automatic update downloads are enabled
[FAIL] Critical security updates do not install automatically
[PASS] System data files and security updates install automatically
▶ CONTROL 2 — BLUETOOTH
─────────────────────────────────────────────────────
[INFO] Bluetooth ControllerPowerState: 1
[WARN] Bluetooth is enabled — disable if not required by end user workflow
▶ CONTROL 3 — REMOTE SERVICES
─────────────────────────────────────────────────────
[WARN] SSH (Remote Login) is active — disable unless required for IT management
[PASS] Screen Sharing is disabled
[PASS] Remote Apple Events is disabled
[PASS] Remote Management (ARD) is not active
▶ CONTROL 4 — SHARING SERVICES
─────────────────────────────────────────────────────
[PASS] File Sharing (SMB/AFP) is disabled
[PASS] Printer Sharing is disabled
[PASS] Internet Sharing is disabled
▶ CONTROL 5 — GATEKEEPER
─────────────────────────────────────────────────────
[INFO] Gatekeeper status: assessments enabled
[PASS] Gatekeeper is enabled — unsigned applications are blocked
▶ CONTROL 6 — FILEVAULT ENCRYPTION
─────────────────────────────────────────────────────
[INFO] FileVault status: FileVault is On.
[PASS] FileVault is enabled — full-disk encryption is active
▶ CONTROL 7 — APPLICATION FIREWALL
─────────────────────────────────────────────────────
[INFO] Firewall state: Firewall is enabled. (State = 1)
[PASS] Application Firewall is enabled
[INFO] Stealth mode: Stealth mode enabled
[PASS] Firewall stealth mode is enabled
▶ CONTROL 8 — SYSTEM INTEGRITY PROTECTION (SIP)
─────────────────────────────────────────────────────
[INFO] SIP status: System Integrity Protection status: enabled.
[PASS] System Integrity Protection is enabled
▶ CONTROL 9 — SCREEN LOCK
─────────────────────────────────────────────────────
[INFO] Login window idle timeout: 300 seconds
[PASS] Login window idle timeout is set to 300 seconds
▶ CONTROL 10 — SECURITY AUDIT LOGGING
─────────────────────────────────────────────────────
[PASS] Security audit daemon (auditd) is running
[INFO] Audit log files present: 14
[PASS] Audit log directory exists at /var/audit
▶ CONTROL 11 — HOME FOLDER PERMISSIONS
─────────────────────────────────────────────────────
[PASS] Home folder permissions for 'akshay' are correctly restricted
[PASS] All home folders have correct permissions
▶ CONTROL 12 — GUEST ACCOUNT
─────────────────────────────────────────────────────
[INFO] Guest account status: Disabled
[PASS] Guest account is disabled
======================================================================
CIS BENCHMARK AUDIT SUMMARY
======================================================================
Host: macbook-pro-akshay
macOS: 14.4.1
Completed: 2025-04-28 10:00:42
Mode: AUDIT ONLY
[PASS] 10 checks passed
[FAIL] 1 checks failed
[WARN] 2 warnings
[MANUAL] 0 require manual intervention
Total: 13 checks evaluated
✗ COMPLIANCE STATUS: NON-COMPLIANT — 1 control(s) failed
Run with --fix to apply safe automated remediations:
sudo ./macos_cis_hardening.sh --fix
Full audit log: /var/log/cis_audit.log
======================================================================
- In Jamf Pro: Settings → Computer Management → Scripts → New
- Paste contents of
macos_cis_hardening.sh - Set Priority:
After - Create a Policy: Computers → Policies → New
- Trigger:
Recurring Check-in - Execution Frequency:
Once every week - Scope to all managed Macs
Policy Name | is | CIS Benchmark Audit
Last Policy Status | is | Failed
The script exits with code 1 when any control fails — Jamf marks the policy as Failed, automatically populating the Smart Group with non-compliant devices.
| Issue | Affected macOS | Detail |
|---|---|---|
systemsetup deprecation |
macOS 13+ (Ventura) | Several systemsetup subcommands are deprecated but remain functional. Deprecation warnings may appear in logs. |
spctl --master-enable/disable |
macOS 15 (Sequoia) | Gatekeeper CLI management changed in Sequoia. Enforce via configuration profile on Sequoia+ devices. |
| SIP modification | All versions | SIP cannot be changed outside of Recovery Mode — this script audits only, never modifies SIP. |
| Screen lock (user session) | All versions | loginWindowIdleTime affects the login window only. User session screen lock is enforced via a Jamf Passcode configuration profile. |
| Skill | Evidence |
|---|---|
| Security compliance | CIS Benchmark knowledge, Level 1 controls, audit vs remediation |
| Bash scripting | Functions, argument parsing, conditionals, counters |
| macOS security internals | spctl, fdesetup, csrutil, socketfilterfw, launchctl, defaults |
| Jamf Pro | Policy deployment, exit code integration, Smart Group automation |
| IT Operations thinking | Audit-first approach, safe remediation, compliance reporting |
| Documentation | Control reference mapping, remediation guide, compatibility notes |
Note: This is a portfolio project demonstrating macOS security operations and CIS Benchmark expertise. Controls are aligned with CIS Apple macOS Benchmark Level 1 guidance. Always test in a non-production environment before deploying fleet-wide.
Author: Akshay Mahaldar — System Operations Engineer | Berlin, Germany LinkedIn: linkedin.com/in/akshay-mahaldar