Setting the stage
If you are new to either the macOS Compliance Project or JAMF Compliance Editor, I would recommend watching and reading the following videos and blog posts on the topic.
- NIST macOS Security & JAMF Compliance Review
- NIST macos security How-To
- 2023 JNUC Presentation on JAMF Compliance Editor
Lets assume for the sake of this blog post that you are familiar with both of these wonderful solutions to baseline compliance on macOS.
For many who use JAMF and the macOS Compliance Project, the use of JAMF Compliance Editor, a GUI tool that helps you to automate the process of picking, and tailoring your baseline for macOS hardening is a no brainer.
It works extremely well and when done it creates a series of useful files that you can use to pass compliance audit but also to systematically enforce baseline settings and configurations to your fleet of macOS workstations or iOS devices.
When you build your baseline it generates a series of folders and files in your “Build” folder area. I created a tailored version of the 800-53r5_moderate baseline so my files are named accordingly with the 800-53r5_moderate as teh file name.
Here are the contents of my /build/800-53r5_moderate folder
- 800-53r5_moderate_compliance.sh: A script you can use to check if a device is in compliance.
- 800-53r5_moderate.adoc - an adoc file you can use to show all the tests that are in scope for your tailored baseline.
- 800-53r5_moderate.html - an HTML file you can use to show all the tests that are in scope for your tailored baseline.
- 800-53r5_moderate.pdf - a PDF file you can use to show all the tests that are in scope for your tailored baseline.
- 800-53r5_moderate.xls - an Excel file you can use to show all the tests that are in scope for your tailored baseline.
- jamfpro - A folder of JAMF Pro specific Computer Extensions to use for smart groups and reporting. It also includes a JSON file of tests that are in scope.
- mobileconfigs - A folder of Mobile Config files that you can deploy to enforce settings in scope for your tailored baseline.
- preferences - A with a file inside it that tells you the tests that are exempt or in scope.
When you build a tailored baseline it creates a JSON File in the /jamfpro folder called 800-53r5_moderate.json (remember your name will be different its named that for me because thats the baseline I am working with).
This file has ALL the items that are included in the baseline even the items you have exempted or removed. You can use this file and create a set of exemptions.
How exactly do you setup Exemptions with the outputted JSON File?
There are a few blog posts that are written out there that have a few tips or tricks that you can follow but no step by step guides that I could find until I found this one.
It at least pointed me in the right direction which was super helpful. Turns out that in essence there are two options.
Option #1 you can use a script that Bob Gendler where you can it against your tailored baseline to generate an exemption json file that you can use in JAMF Pro.
Option #2 you can use the JSON file that comes as a standard output file located in the /build/
Both steps assume that you have deployed the compliance script, the mobileconfig files and he preference file in the /preferences folder.
The importance of Preference Naming
Before we move forward lets be clear on a few concepts with the macOS Compliance Project and the JAMF Compliance Editor. The name of the files and the name of the preferences matter, greatly.
When you use the JAMF Compliance Editor and you build a baseline it comes with a set of premade scripts that is to be used as a Computer Extension in JAMF.
- compliance-FailedResultsList.sh: A script that will return a list of failed tests that are not passing the baseline test.
- compliance-exemptions.sh: A script that reads the preference file for exemptions that you may have set locally on each machine.
- compliance-FailedResultsCount.sh: A script that counts the number of failed tests. Useful for creating smart groups or reporting on non compliant devices.
- compliance-version.sh: A script that lists the version of the baseline that you are testing for on a specific machine.
Lets take a look at each script so you can understand what file its looking for on the Mac in question so you can understand what preference domain that you must use for each item that you use in JAMF that comes from the JAMF Compliance Editor.
Lets take a look at the compliance-FailedResultsList.sh in this file it specifically is looking for a file by running the following variable.
audit=$(/bin/ls -l /Library/Preferences | /usr/bin/grep 'org.*.audit.plist' | /usr/bin/awk '{print $NF}')Its looking for a file named org.800-53r5_moderate.audit.plist, I know this because the wildcard in the variable above is a placeholder for the name of my baseline which happens to be as mentioned 800-53r5_moderate.
The org.800-53r5_moderate.audit.plist file is included in the /build/
This file is important to deploy to your endpoints because its the preference file that the script and the computer extensions will use to know which baseline to test your system on.
Lets now take a look at compliance-FailedResultsCount.sh in this file it specifically is looking for a file by running the following variable.
audit=$(/bin/ls -l /Library/Preferences | /usr/bin/grep 'org.*.audit.plist' | /usr/bin/awk '{print $NF}')Wait the variable s the same, its looking for the same preference name? Is that correct? YES! The naming convention here is the same but if you look further down the script you will see
exemptfile="/Library/Managed Preferences/${audit}"That it calls that audit variable just for the name but references a new location for the exemptions. So we have 2 preference files one in
/Library/Preferences/ - Which is where the tests that are in scope are defined /Library/Managed Preferences/ - Which is where the tests that are out of scope are defined
Both have the same preference domain. This confused me a bit at first so I wanted to call this out as it was not fully clear to me in any blog posts or documentation items.
Option #1: Generate a clean JSON with Script
DISCLAIMER You only NEED to do this step if you are using the macOS Compliance Project without the JAMF Compliance Editor.
As mentioned Bob Gendler wrote a script that you can use to create a JSON file for the purposes of creating the preference file that will live in the Library/Managed Preferences/ folder.
Certain security baselines enforce the use of Common Access Cards (CAC) for authentication. While this may be necessary for larger organizations, it might not be practical for a small business. To disable this requirement, simply update the preference file by changing
Manually managing these kinds of exceptions can quickly become time-consuming and prone to errors. Using the above script, it generates a structured JSON file that can be uploaded to Jamf, making it easy to toggle specific rules on or off as needed.
To use it, place the script inside the scripts directory of your project, then execute the following command:
$ ./scripts/generate_json.py /build/baselines/<name of your custom baseline exemptions only>.yamlApplying the script to a full baseline as stated here, can result in an extensive JSON file that has ALL of your baseline items including those that are in scope. To make it more manageable, I created a separate version of the file with _exempt added to its name. I then went through and eliminated any rules that would never need exemptions, significantly reducing both the number of rules and the overall file size.
Once you have the JSON File you can upload it to JAMF Pro as outlined here
- Log in to Jamf Pro.
- Navigate to Computers > Configuration Profiles.
- Click New to create a new configuration profile.
- Under the Options tab, choose Application & Custom Settings.
- Click + Add and select Custom Schema.
- Enter the Preference Domain for the application. You must choose the preference org.*.audit.plist where the wildcard is your baseline name
- Click Upload Schema and select your JSON file.
- Once uploaded, verify that the settings appear correctly in the Jamf UI.
The benefit of this step is that the JSON file you upload is the delta or the exceptions of the tailored baseline so all of the items you will configure will be selected and you can select them all vs scanning through a large file of ALL items and only selecting the few that are true exemptions.
Configuring Exemptions in the Custom Schema
- Navigate to the Configuration Profile
- In Jamf Pro, go to Computers > Configuration Profiles.
- Select the profile where you uploaded the JSON schema.
- Modify Properties Based on Your Organization’s Needs
- Locate the Preference Domain (e.g., org.cis_lvl2_puck.audit.plist).
- Click Add/Remove Properties to customize the settings.
- Setting an Exemption
- Identify the rule you want to modify (e.g., os_httpd_disable).
- Set the exempt field to true or false: – true means the setting is being exempted. – false means the rule is enforced.
- If exempt = true, an exempt_reason is required.
- Example: “web server required for app testing”
Option #2: Use the JSON that comes with your build
Using Jamf Compliance Editor (JCE) simplifies the process of generating a .json file for external application preferences in Jamf Pro. However, this file includes all baseline items—even those not in scope—so some manual cleanup may be required. Below are the detailed steps to create and configure an external application preference using JCE and a JSON schema.
Generate the JSON Schema Using Jamf Compliance Editor
- Open Jamf Compliance Editor and load your baseline.
- Click Build to generate the JSON schema.
- Locate the file in:
/build/<your_baseline_name>/jamfpro/<your_baseline_name>.json- Modify the JSON file if necessary:
- Remove unnecessary rules to exclude out-of-scope items manually.
- Alternatively, you can leave all rules in place and disable out-of-scope items later in Jamf Pro.
Upload the JSON Schema to Jamf Pro
- Log in to Jamf Pro.
- Navigate to Computers > Configuration Profiles and click New.
- In the General payload, provide a profile name and description.
- Select Application & Custom Settings and click Configure.
- Choose Custom Schema as the source.
- Set the Preference Domain: – This is critical—it must match the application’s preference domain, e.g., com.example.app.
- Copy and paste the JSON schema into the Custom Schema field.
- Click Save to apply changes.
Configuring Exemptions in the Custom Schema
- Navigate to the Configuration Profile
- In Jamf Pro, go to Computers > Configuration Profiles.
- Select the profile where you uploaded the JSON schema.
- Modify Properties Based on Your Organization’s Needs
- Locate the Preference Domain (e.g., org.cis_lvl2_puck.audit.plist).
- Click Add/Remove Properties to customize the settings.
- Setting an Exemption
- Identify the rule you want to modify (e.g., os_httpd_disable).
- Set the exempt field to true or false: – true means the setting is being exempted. – false means the rule is enforced.
- If exempt = true, an exempt_reason is required.
- Example: “web server required for app testing”
Conclusion
I hope this blog post outlines the steps clearly for those that need to use the exemptions feature of the macOS compliance project and the JAMF Compliance Editor to work with the provided reporting computer extensions in JAMF Pro correctly.
Understanding that the preference domain is the glue that holds this configuration all together is critical to ensuring that the computer extensions run correctly and that your preferences for exempt items in your baseline are deployed to each in scope workstation.
If you found this post useful, Follow me and comment with questions, or feedback. As always here are the sources I referenced throughout this blog post.
Sources
- JAMF Github Repo
- Bob Gendler: generate_json.py
- NIST macOS Security & JAMF Compliance Review
- Customize the App using JAMF Pro
- NIST macos security How-To
- 2023 JNUC Presentation on JAMF Compliance Editor
AI Usage Transparency Report
AI Era · Written during widespread use of AI tools
AI Signal Composition
Score: 0.36 · Moderate AI Influence
Summary
If you are new to either the macOS Compliance Project or JAMF Compliance Editor, I would recommend watching and reading the following videos and blog posts on the topic. Familiarizing yourself with these resources will help ensure a smoother understanding of the project's requirements and functionality. This will also enable you to better navigate the tools and make informed decisions about your compliance setup.
Related Posts
Automating JAMF Pro Email Notifications with SendGrid (Smart Group Driven Workflows)
Modern device management isn't just about enforcing policies—it's about communicating effectively with users at the right time. In JAMF Pro, Smart Groups give you powerful visibility into device state, but they don't natively solve the problem of proactive, automated user communication. Whether you're trying to prompt users to restart their machines, complete updates, or take action on compliance issues, bridging that gap requires a flexible and scalable notification system.
Leaving Flickr: Migrating 20,000+ Photos to Synology and Taking Back Control
There’s a certain kind of friction you start to notice when you’ve been using a service for a long time. Not enough to make you leave immediately, but enough to make you pause. Flickr had been that kind of service for me. It quietly held years of photos, uploads from old phones, albums I hadn’t looked at in ages, and a massive "Auto Upload" collection that had grown into something I didn’t fully understand anymore.
Exploring the Apple Business Manager API: A Hands-On Playground
If you’ve ever tried to talk directly to the **Apple Business Manager (ABM) API**, you already know the process can feel like deciphering a secret code. Between private keys, encrypted certificates, ES256 signatures, and OAuth2 flows... there’s a lot going on under the hood. This complexity is what makes direct communication with ABM so challenging, requiring a deep understanding of its intricacies to navigate successfully.
Updating Safari on macOS with Jamf Pro: Three Practical Strategies
Keeping Safari updated is one of the simplest ways to harden a macOS fleet. Apple ships security fixes for Safari frequently, and those patches often land before a full macOS point release. This means that by keeping Safari up-to-date, you can ensure your users have access to the latest security protections without having to wait for a major operating system update. If Safari is lagging behind, your users are browsing the web with a larger attack surface than necessary.
Hunting Down Jamf Profile Payloads with Python
If you've spent enough time living inside Jamf Pro, you eventually run into the same problem: someone set a configuration somewhere, sometime, and nobody remembers where. It might be something obscure – a certificate payload, a conditional SSO predicate, or that one security preference quietly misbehaving on three machines in accounting. And when you have dozens of configuration profiles, each with multiple payloads, nested keys, and XML-wrapped values, finding that setting can feel like forensic archaeology.
Keeping Jamf Security Cloud Current for Microsoft 365: Updated Routing Policies
When I first wrote about troubleshooting Standard Routing Policies in Jamf Security Cloud, the goal was simple: help admins keep Microsoft Teams and Microsoft 365 traffic flowing smoothly through Jamf Trust + App-Based VPN. This straightforward objective remains unchanged, as the complexities of network configurations can often lead to frustrating issues that hinder productivity.
Ensuring Jamf Trust VPN Stays Connected with Jamf Pro
Keeping your organization's VPN always connected is crucial—especially with Zero Trust Network Access (ZTNA) frameworks like **Jamf Trust**. One of the challenges with **Jamf Trust** is that it does *not* automatically open or reconnect on startup or login by default. However, with a combination of Jamf Pro policies, a custom script, and an extension attribute, you can ensure your users stay securely connected at all times, even when their devices are restarted or logged out. This setup helps maintain continuous access to network resources while adhering to the security standards...
Troubleshooting Standard Routing Policies in JAMF Security Cloud
As a fairly new administrator of JAMF Security Cloud, it was the ease of which its administration that admittedly drew me in. Quite an elegant solution for securing the various apps on business workstations with premade app-based VPN routing rules built right in, I was hooked. The concept is simple: turn on the policies, create your enrollment, and deploy – and you're done. This straightforward approach has made it easy to integrate into our existing workflow, allowing us to focus on more critical tasks.
Enrolling M1-M4 Devices into Automox with JAMF with secure tokens
Managing Secure Tokens on macOS has long been a challenge for administrators using JAMF and Automox. In my previous post, Managing the macOS Secure Token with JAMF Pro, I discussed a script-based approach to grant Secure Tokens to additional users. However, this method required administrators to manually pass usernames and passwords into the JAMF configuration—an approach that, while effective, was not ideal from a security or usability perspective. This manual process introduced unnecessary risks and added complexity to the overall management of Secure Tokens.
Modified JAMF Compliance Editor Extension: List failed items NOT in exemption list
As promised I am continuing to look for ways to build out my JAMF Github Repo. One of the items that I have been working heavily with in my role is the macOS Compliance Project and as I am a JAMF administrator that means leveraging the JAMF Compliance Editor. The JAMF Compliance Editor gives you the ability to rapidly configure, tailor and deploy a custom baseline with the macOS Compliance Project.