Skip to main content
CIS Benchmarks are consensus-based secure configuration guides used to harden systems, software, and networks — an industry-recognized baseline to reduce attack surface. Use them with Primo and FleetDM to assess compliance and enforce settings across your macOS and Windows fleet.

OS support

macOSWindowsLinuxiOS / iPadOSAndroid
✅ macOS 13+✅ Windows 10+ Enterprise

About CIS Benchmarks

CIS Benchmarks are community-developed through an open consensus process (CIS WorkBench) with government, industry, and academia. There are 100+ benchmarks across 25+ vendor families. Each benchmark ships with two profiles:
  • Level 1: prudent, low-impact settings that provide clear security value.
  • Level 2: stronger, defense-in-depth settings that may affect usability/performance.

How to add CIS Benchmarks

Run this script to generate the CIS policies queries YAML file for your FleetDM instance:
#!/bin/bash
#shellcheck disable=SC2207

# convert.cis.policy.queries.yml @2024 Fleet Device Management

# CIS queries as written here:
#    https://github.com/fleetdm/fleet/blob/main/ee/cis/macos-14/cis-policy-queries.yml
# must be converted to be uploaded via Fleet GitOps.
#
# This script takes as input the YAML from the file linked above & creates a new YAML array compatible with the "Separate file" format documented here:
#    https://fleetdm.com/docs/configuration/yaml-files#separate-file

# get CIS queries raw file from Fleet repo
cisfile='https://raw.githubusercontent.com/fleetdm/fleet/refs/heads/main/ee/cis/macos-14/cis-policy-queries.yml'
cispath='/private/tmp/cis.yml'

/usr/bin/curl -X GET -LSs "$cisfile" -o "$cispath"

# create CIS benchmark array
IFS=$'\n'
cisarry=($(/opt/homebrew/bin/yq '.spec.name' "$cispath" | /usr/bin/grep -v '\-\-\-'))

for i in "${cisarry[@]}"
do
    cisname="$(/opt/homebrew/bin/yq ".[] | select(.name == \"$i\") | (del(.platforms)) | (del(.purpose)) | (del(.tags)) | (del(.contributors))" "$cispath" | /opt/homebrew/bin/yq eval '.name')"
    cispfrm="$(/opt/homebrew/bin/yq ".[] | select(.name == \"$i\") | (del(.platforms)) | (del(.purpose)) | (del(.tags)) | (del(.contributors))" "$cispath" | /opt/homebrew/bin/yq eval '.platform')"
    cisdscr="$(/opt/homebrew/bin/yq ".[] | select(.name == \"$i\") | (del(.platforms)) | (del(.purpose)) | (del(.tags)) | (del(.contributors))" "$cispath" | /opt/homebrew/bin/yq eval --unwrapScalar=true '.description')"
    cisrslt="$(/opt/homebrew/bin/yq ".[] | select(.name == \"$i\") | (del(.platforms)) | (del(.purpose)) | (del(.tags)) | (del(.contributors))" "$cispath" | /opt/homebrew/bin/yq eval --unwrapScalar=true '.resolution')"
    cisqrry="$(/opt/homebrew/bin/yq ".[] | select(.name == \"$i\") | (del(.platforms)) | (del(.purpose)) | (del(.tags)) | (del(.contributors))" "$cispath" | /opt/homebrew/bin/yq eval --unwrapScalar=true '.query')"

    printf "name: %s\nplatform: %s\ndescription: |\n%s\nresolution: |\n%s\nquery: |\n%s\n" "$cisname" "$cispfrm" "$cisdscr" "$cisrslt" "$cisqrry" | /usr/bin/sed 's/^/    /g;s/^[[:space:]]*name:/- name:/;s/^[[:space:]]*platform:/  platform:/;s/^[[:space:]]*description:/  description:/;s/^[[:space:]]*resolution:/  resolution:/;s/^[[:space:]]*query:/  query:/'

done
Then upload the policies to your FleetDM instance:
fleetctl apply --policies-team "Workstations" -f cis-policy-queries.yml

Where MDM tools fit (Fleet/Primo)

Fleet exposes policy queries to assess CIS compliance on macOS 13+ and Windows 10+ (Enterprise). Policies do not remediate — you still need MDM profiles and/or scripts to enforce settings, and you can use automations to drive remediation workflows. Some checks require MDM enrollment and specific agent permissions.

On macOS

Disk encryption

This policy is templated with Primo and works for both macOS and Windows devices.
  1. On Primo, go to MDM > Profiles
  2. Select all devices
  3. Click on the card: Encryption
  4. Click on “Turn on setting”
  5. Finally, confirm. Screenshot: Disk Encryption

Password policy and automatic screen lock

Short lock timeouts and strong passwords help prevent attacks like shoulder-surfing, insider misuse, and opportunistic access on unattended laptops. This policy is templated with Primo and works for iOS, macOS and Windows devices.
  1. On Primo, go to MDM > Profiles
  2. Select all devices
  3. Click on the card: Password & Screen lock
  4. Click on “Turn on setting”
  5. Navigate to Mac, Windows and iOS tabs to configure each one.
  6. Finally, confirm.

Built-in firewall

Screenshot: Password policy & Automatic ScreenLock Default-deny inbound traffic reduces the chance that a dormant service becomes a network entry point, especially on public Wi-Fi. This policy is templated with Primo and works for both macOS and Windows devices.
  1. On Primo, go to MDM > Profiles
  2. Select all devices
  3. Click on the card: Firewall
  4. Click on “turn on setting”
  5. Finally, confirm. Screenshot: Built-in Firewall

Firewall stealth mode

Hiding from ICMP and similar probes makes devices harder to enumerate in scans and slows worm propagation. This policy is not templated with Primo and needs to be configured as a Custom Profile Setting.
  1. On Primo, go to MDM > Profiles
  2. Select all devices
  3. Click on the card: Add a custom MDM setting
  4. Give it a name (i.e. Block ICMP) and a description (i.e. the description above)
  5. For macOS, upload the following mobileconfig
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>PayloadType</key>
        <string>Configuration</string>
        <key>PayloadVersion</key>
        <integer>1</integer>
        <key>PayloadIdentifier</key>
        <string>com.getprimo.cis.6EC2A11D-313F-410F-B2FA-80F1D726624A</string>
        <key>PayloadUUID</key>
        <string>AE317001-B5E0-4F78-B971-954506775306</string>
        <key>PayloadDisplayName</key>
        <string>Firewall Stealth Mode</string>
        <key>PayloadRemovalDisallowed</key>
        <true/>
        <key>PayloadContent</key>
        <array>
            <dict>
                <key>PayloadType</key>
                <string>com.apple.security.firewall</string>
                <key>PayloadVersion</key>
                <integer>1</integer>
                <key>PayloadIdentifier</key>
                <string>com.getprimo.cis.stealth</string>
                <key>PayloadUUID</key>
                <string>B852FF89-DBE2-4F85-BE9C-20D180F5C859</string>
                <key>EnableStealthMode</key>
                <true/>
            </dict>
        </array>
    </dict>
</plist>
  1. Finally, confirm.

On Windows

Disk encryption

This policy is templated with Primo and works for both macOS and Windows devices. Follow the same steps as the macOS Disk Encryption section above — the Encryption card in profiles applies to both platforms.

Password policy and automatic screen lock

This policy is templated with Primo and works for iOS, macOS and Windows devices. Follow the same steps as the macOS Password policy section above. Make sure to configure the Windows tab separately.

Built-in firewall

This policy is templated with Primo and works for both macOS and Windows devices. Follow the same steps as the macOS Built-in Firewall section above — the Firewall card in profiles applies to both platforms.