New hardware models appearing as 21.5 inch iMacs in Apple Business Manager and Apple School Manager

Apple recently released new hardware models for Mac Minis and MacBook Pros which use Apple’s M4 processors. As those new machines are purchased by companies, schools or institutions and get loaded into those organization’s Apple Business Manager (ABM) or Apple School Manager (ASM) instances though, new device listings for M4 Mac Minis and M4 MacBook Pros aren’t appearing. What is appearing are 21.5 inch iMacs, which does not appear to be an iMac hardware model that Apple is selling as of November 2024.

Why is this? I’ve observed over time that the 21.5 inch iMac listing is what appears for new hardware models in ABM / ASM when Apple hasn’t yet updated ABM / ASM with the information for the newly-released hardware model.

You should be able to confirm in ABM / ASM if the part number listed for the Mac in question matches up with what you’re expecting, in place of being the part number for a 21.5 inch iMac. In this example, the part number appearing is MX2E3ZE/A, which corresponds to a part number for a 2024 14 inch MacBook Pro.

Historically, once Apple updated ABM / ASM with the updated hardware model information, this display issue in ABM / ASM has corrected itself. Affected device listings switched from displaying as 21.5 inch iMacs to whatever actual hardware model the device is.

Managing user notifications for apps which request screen access on macOS Sequoia 15.1

As part of the macOS Sequoia 15.1 release notes, this section is included:

MDM profiles can use the new key ‘forceBypassScreenCaptureAlert’, which allows owners of managed devices to opt out of user notifications for content capture technologies. (131327961)

What’s this note discussing? It’s referring to a user notification that Apple introduced in macOS Sequoia for apps which request screen access but aren’t using Apple’s SCContentSharingPickerMode API to do so. A good example is the user notification for the Zoom app, which uses screen access for video conferencing.

These user notifications appear monthly and request the user to choose whether or not they want to allow this access for the app in question.

For Mac environments which want to manage these notifications and prevent them from being displayed to their users, Apple has provided management options as part of macOS Sequoia 15.1. For more details, please see below the jump.

The relevant preference domain and key values are listed below:

  • Preference domain: com.apple.applicationaccess
  • Key: forceBypassScreenCaptureAlert
  • Value: Boolean

It’s important to note that while this management setting works on macOS Sequoia 15.1, it is not available to macOS Sequoia 15.0.1, 15.0.0 or earlier versions of macOS.

These settings can be managed by a configuration profile, where setting a boolean value of true will disable the user notifications. Please see below for an example profile. The example profile is also available via the following link:

https://github.com/rtrouton/profiles/tree/main/DisableScreenAccessRequestUserNotifications


<?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"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadIdentifier</key>
<string>com.apple.applicationaccess.C70F311D-B330-4620-9097-F98FD7E39E33</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadUUID</key>
<string>C70F311D-B330-4620-9097-F98FD7E39E33</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>forceBypassScreenCaptureAlert</key>
<true/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Disables user notifications for apps which request screen access</string>
<key>PayloadDisplayName</key>
<string>Disable Screen Access Request User Notifications</string>
<key>PayloadIdentifier</key>
<string>1A6E3566-0112-40F7-A49F-416D99C61566</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>1A6E3566-0112-40F7-A49F-416D99C61566</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

Note: If you’re planning to use the example profile with Jamf Pro, it will need to be signed before it can be uploaded to Jamf Pro. If you’re not familiar with how to sign profiles, the post linked below is a good guide to how that process works:

https://macblog.org/sign-configuration-profiles/

As an alternative, you can use the Application & Custom Settings profile payload in Jamf Pro with the plist shown below to create a profile with the same functionality as the example profile.


<?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"&gt;
<plist version="1.0">
<dict>
<key>forceBypassScreenCaptureAlert</key>
<true/>
</dict>
</plist>

Suppressing Apple Intelligence notifications on macOS Sequoia

As part of Apple’s rollout of Apple Intelligence, there’s a Notification Center notification which may appear on macOS 15.1 and later which prompts you to try using Apple Intelligence.

Shops who want to block use of Apple Intelligence for security reasons may also want to stop these notifications from appearing. This is possible to do once you have the bundle identifier for the notification in question. Thanks to excellent detective work by colleagues in the Mac Admins Slack, the correct bundle identifier for this notification has been identified as the following:

_SYSTEM_CENTER_:com.apple.followup.alert

Once you have the bundle identifier, you can put this into a configuration profile which manages notification settings to block these notifications from appearing. For more details, please see below the jump.

Please see below for an example profile. This profile is also available via the following link:

https://github.com/rtrouton/profiles/tree/main/SuppressAppleIntelligenceNotifications


<?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"&gt;
<plist version="1">
<dict>
<key>PayloadUUID</key>
<string>1B270908-4F78-4ADD-A97D-EEFD21AD3732</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadIdentifier</key>
<string>1B270908-4F78-4ADD-A97D-EEFD21AD3732</string>
<key>PayloadDisplayName</key>
<string>Suppress Apple Intelligence notifications</string>
<key>PayloadDescription</key>
<string/>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Notifications Payload</string>
<key>PayloadIdentifier</key>
<string>7B5578BC-11E6-45B1-A84F-61708AD47711</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadType</key>
<string>com.apple.notificationsettings</string>
<key>PayloadUUID</key>
<string>7B5578BC-11E6-45B1-A84F-61708AD47711</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>NotificationSettings</key>
<array>
<dict>
<key>BundleIdentifier</key>
<string>_SYSTEM_CENTER_:com.apple.followup.alert</string>
<key>CriticalAlertEnabled</key>
<false/>
<key>NotificationsEnabled</key>
<false/>
</dict>
</array>
</dict>
</array>
</dict>
</plist>

Managing Apple Intelligence features on macOS Sequoia 15.1

As part of the release of macOS Sequoia, Apple has provided management options on macOS for Apple Intelligence features. While not all of these Apple Intelligence features may be available as of macOS 15.1 in all areas of the world, use of these new features may not be acceptable for security reasons in all Mac environments. Having these management options available now allows Mac admins to get management of these features in place before Apple makes them available. For more details, please see below the jump.

As of macOS 15.1, management options are available for the following Apple Intelligence functionality:

The relevant preference domain and key values are listed below:

 

Genmoji

  • Preference domain: com.apple.applicationaccess
  • Key: allowGenmoji
  • Value: Boolean

Image Playground

  • Preference domain: com.apple.applicationaccess
  • Key: allowImagePlayground
  • Value: Boolean

Writing Tools

  • Preference domain: com.apple.applicationaccess
  • Key: allowWritingTools
  • Value: Boolean

Summarize emails

  • Preference domain: com.apple.applicationaccess
  • Key: allowMailSummary
  • Value: Boolean

 

It’s important to note that while all of the settings listed above work on macOS Sequoia 15.1, not all the settings work on macOS Sequoia 15.0.0 and 15.0.1. Here’s the compatibility list:

macOS 15.0 and later:

  • allowGenmoji
  • allowImagePlayground
  • allowWritingTools

macOS 15.1 and later:

  • allowMailSummary

 

These settings can be managed by a configuration profile, where setting a boolean value of false will disable the Apple Intelligence feature in question. Please see below for example profiles. The example profiles are also available via the following links:

 

Genmoji


<?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"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadIdentifier</key>
<string>com.apple.applicationaccess.1281701E-9695-4447-9028-4962C25162FF</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadUUID</key>
<string>1281701E-9695-4447-9028-4962C25162FF</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>allowGenmoji</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Disables creation of new Genmoji</string>
<key>PayloadDisplayName</key>
<string>Apple Intelligence Disable Genmoji</string>
<key>PayloadIdentifier</key>
<string>B83678F5-B2CB-467C-A89F-73F2E2E1346C</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>B83678F5-B2CB-467C-A89F-73F2E2E1346C</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

 

Image Playground


<?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"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadIdentifier</key>
<string>com.apple.applicationaccess.4FDE23F1-2652-4653-813C-205C9B86C0F5</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadUUID</key>
<string>4FDE23F1-2652-4653-813C-205C9B86C0F5</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>allowImagePlayground</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Disables Image Playground and prohibits the use of image generation</string>
<key>PayloadDisplayName</key>
<string>Apple Intelligence Disable Image Playground</string>
<key>PayloadIdentifier</key>
<string>5596EE02-5B47-4B4C-B3F0-AA531C1E9AEB</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>5596EE02-5B47-4B4C-B3F0-AA531C1E9AEB</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

 

Writing Tools


<?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"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadIdentifier</key>
<string>com.apple.applicationaccess.2C74FDD6-E3CD-4E3B-9193-CD4818452895</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadUUID</key>
<string>2C74FDD6-E3CD-4E3B-9193-CD4818452895</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>allowWritingTools</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Disables Apple Intelligence writing tools</string>
<key>PayloadDisplayName</key>
<string>Apple Intelligence Disable Writing Tools</string>
<key>PayloadIdentifier</key>
<string>FDDB4857-545D-4538-9C0B-B8ED78FFCE3E</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>FDDB4857-545D-4538-9C0B-B8ED78FFCE3E</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

 

Summarize emails


<?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"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadIdentifier</key>
<string>com.apple.applicationaccess.6DD01B26-8368-45FE-A4F7-35F4CD153E5D</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadUUID</key>
<string>6DD01B26-8368-45FE-A4F7-35F4CD153E5D</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>allowMailSummary</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Disables Mail Summary and prohibits the ability to create email summaries</string>
<key>PayloadDisplayName</key>
<string>Apple Intelligence Disable Mail Summary</string>
<key>PayloadIdentifier</key>
<string>45B76C44-A61D-4A1B-82B9-6118B18DB129</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>45B76C44-A61D-4A1B-82B9-6118B18DB129</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

Disabling iPhone mirroring on macOS Sequoia

iPhone mirroring is a new feature as of macOS Sequoia, which acts as a screen sharing method for an iPhone from a Mac. It allows the use of an iPhone from a nearby Mac by displaying the iPhone’s screen within an iPhone Mirroring.app window and allowing the Mac user to interact with the iPhone’s screen, including being able to access its apps and notifications.

This new screen sharing capability may not be acceptable for security reasons in all Mac environments, so Apple has provided management options for disabling the use of iPhone mirroring. For more details, please see below the jump.

The relevant preference domain and key values are below:

  • Preference domain: com.apple.applicationaccess
  • Key: allowiPhoneMirroring
  • Value: Boolean

This setting can be managed by a configuration profile, where setting a boolean value of false will disable iPhone mirroring and prevent it from working. Please see below for an example profile. This profile is also available via the following link:

https://github.com/rtrouton/profiles/tree/main/BlockiPhoneMirroring


<?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"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Restrictions</string>
<key>PayloadIdentifier</key>
<string>com.apple.applicationaccess.DD8454BB-A1D6-4DD9-B1AC-C1B6ABA512E9</string>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadUUID</key>
<string>DD8454BB-A1D6-4DD9-B1AC-C1B6ABA512E9</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>allowiPhoneMirroring</key>
<false/>
</dict>
</array>
<key>PayloadDescription</key>
<string>Blocks the use of iPhone mirroring</string>
<key>PayloadDisplayName</key>
<string>Block iPhone Mirroring</string>
<key>PayloadIdentifier</key>
<string>D0B2E096-2C7F-4F2F-A1C0-FFE16919768B</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>D0B2E096-2C7F-4F2F-A1C0-FFE16919768B</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

Managed Apple Accounts which were out of scope for ABM or ASM federation may be changed to be in scope by the federation process

In Apple Business Manager (ABM) or Apple School Manager (ASM), you can link to your identity provider (IdP) to ABM and ASM. This allows folks to sign in to Apple devices with the same username and password that they use to log into systems used at their company, school or institution. Apple refers to this as federated authentication and supports this by creating Managed Apple Accounts (MAA) with the username and email address of the user in question, where that information is being provided by that company, school or institution’s IdP. Once this federation process is completed, when someone tries to use their MAA to log into an Apple system, they’ll be provided with the login screen for that company, school or institution’s IdP, in place of using Apple’s own authentication system for Apple Accounts.

However, prior to the federation process happening, a company, school or institution may have manually created MAAs in ABM / ASM for various purposes and want them to keep using Apple’s own authentication system for Apple Accounts in place of authentication using their company, school or institution’s IdP.

This usually applies to MAAs which are used as service accounts in ABM / ASM, where there may only an email alias set up in place of an actual user account set up in the IdP for that MAA. In those scenarios, if there’s no actual user account in the IdP for that MAA, authentication becomes impossible if ABM or ASM is forwarding authentication requests to the IdP.

The best practice in this case is to assign the MAAs in question to a domain which is different from the one being federated. So if you’re planning to federate accounts in the company.com domain, you would set up a different domain in ABM or ASM which is not company.com and assign those MAAs to that different domain. However, there’s an additional step to take as part of this domain re-assignment process. In addition to assigning the MAA to a different domain, you also need to make sure that the associated email address used with the MAA is also not part of the domain you’re planning to federate.

Why is this? As part of the documentation Apple provides for the federation process , there’s this note in the Before you begin section:

For existing users with an email address in the federated domain, their Managed Apple ID is automatically changed to match that email address.

What’s this mean? It means that the existing MAA may be set up with the following username and email:

  • Username: something@outside_domain_being_federated.com
  • Email: something@domain_being_federated.com

However, once the initial federation process has happened the MAA username and email will now look like this:

  • Username: something@domain_being_federated.com
  • Email: something@domain_being_federated.com

Now the previously outside-of-federation-scope MAA ( something@outside_domain_being_federated.com ) is in scope for being federated by having its MAA changed to something@domain_being_federated.com. In turn, this change means that authentication requests for the something@domain_being_federated.com MAA are being sent on to the company, school or institution’s IdP. That IdP may not actually have a user account for the something@domain_being_federated.com MAA or be able to authenticate it, which means you can’t log into that MAA.

How do you address this? My recommendation is that prior to federation, you identify all the MAAs you want to remain outside of scope and assign them an email address which is explicitly outside of the domain you’re planning to federate. For example, if your MAA is currently like this:

  • Username: something@outside_domain_being_federated.com
  • Email: something@domain_being_federated.com

Change it to something like this:

  • Username: something@outside_domain_being_federated.com
  • Email: something@work_email_domain_which_is_not_the_domain_being_federated.com

As far as I know, this is a one-time change which is made by the initial ABM / ASM federation process. But I do not know that with 100% certainty, so please make sure to ask the folks at Apple about this issue if you’re planning an ABM / ASM federation process and have existing MAAs which may be affected by this.

Successfully run sudo commands are no longer logged by default to unified logging on macOS Sequoia

On macOS, you can use macOS’s unified logging to display commands run using the sudo command line tool. On macOS Sonoma and earlier, both successful and unsuccessful commands were logged by default. For example, here’s what you would see on macOS Sonoma when the following command was run first unsuccessfully and then successfully:


sudo date

view raw

gistfile1.txt

hosted with ❤ by GitHub

Assuming you ran this command within the past three hours, you could use the following command to see both the successful and unsuccessful attempts to run the command above in the unified logs:


log show –style syslog –predicate 'process == "sudo" AND composedMessage CONTAINS "COMMAND"' –last 3h

view raw

gistfile1.txt

hosted with ❤ by GitHub

On macOS Sonoma, you should see both the successful and unsuccessful attempts to run the sudo date command (along with any other successful and unsuccessful attempts to use the sudo command.)

However, on macOS Sequoia if you run the same set of successful and unsuccessful attempts and then run the log command shown above, you would only see the unsuccessful attempts in the unified logs:

Why is this? For more details, please see below the jump.

On macOS Sequoia and earlier, the sudo command’s behavior is defined by the sudoers configuration file stored in the /etc directory. For macOS Sequoia, the following section was added to the /etc/sudoers configuration file:


# Remove this line to log successful sudo launches. May contain sensitive
# information passed as arguments to the command
Defaults !log_allowed

view raw

gistfile1.txt

hosted with ❤ by GitHub

The !log_allowed setting means that the sudo command should not log allowed, or successful, attempts to run the sudo command. That means only the not allowed, or unsuccessful, commands will get logged to the unified logging.

If you want to configure the logging to use the pre-Sequoia behavior, you can edit the /etc/sudoers configuration file in one of the following ways:

1. Comment out the new !log_allowed line:


# Remove this line to log successful sudo launches. May contain sensitive
# information passed as arguments to the command
# Defaults !log_allowed

view raw

gistfile1.txt

hosted with ❤ by GitHub

2. Remove the new !log_allowed line:


# Remove this line to log successful sudo launches. May contain sensitive
# information passed as arguments to the command

view raw

gistfile1.txt

hosted with ❤ by GitHub

Once the /etc/sudoers configuration file has been edited to either comment out or remove the new !log_allowed line, the sudo command on macOS Sequoia should log both successful and unsuccessful commands to the unified logging.

Setting Safari to always prompt for download location on macOS Sequoia

One of the options in Safari is to set a location for file downloads to go to. By default, this is set to the Downloads directory in the logged-in user’s home folder.

An alternative option is to set Safari to always prompt for a download location. 

 

For those who want to set the option for Safari to always prompt for a download location, it is possible to set this on macOS Sequoia using the com.apple.Safari.SandboxBroker preference domain. For more details, please see below the jump.

The relevant preference domain and key values are below:

  • Preference domain: com.apple.Safari.SandboxBroker
  • Key: AlwaysPromptForDownloadFolder
  • Value: Boolean

 

This can be set for the logged-in user using the following defaults command:


defaults write com.apple.Safari.SandboxBroker AlwaysPromptForDownloadFolder -bool true

view raw

gistfile1.txt

hosted with ❤ by GitHub

 

This setting can also be managed by a configuration profile. Please see below for an example profile:


<?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"&gt;
<plist version="1">
<dict>
<key>PayloadUUID</key>
<string>572C7A43-A6A4-4A68-817D-352C0FD0FC72</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadIdentifier</key>
<string>572C7A43-A6A4-4A68-817D-352C0FD0FC72</string>
<key>PayloadDisplayName</key>
<string>Safari Always Prompt for Download Location</string>
<key>PayloadDescription</key>
<string />
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true />
<key>PayloadRemovalDisallowed</key>
<true />
<key>PayloadScope</key>
<string>System</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Custom Settings</string>
<key>PayloadIdentifier</key>
<string>5C19AE28-76ED-4B00-ABD8-B9B76EA88287</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadUUID</key>
<string>5C19AE28-76ED-4B00-ABD8-B9B76EA88287</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadContent</key>
<dict>
<key>com.apple.Safari.SandboxBroker</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>AlwaysPromptForDownloadFolder</key>
<true />
</dict>
</dict>
</array>
</dict>
</dict>
</dict>
</array>
</dict>
</plist>

Using certificate public keys to create dummy MDM configuration profiles for Jamf Pro device smart group scoping

My teammates at Jamf who support Jamf’s own IT (known as Jamf @ Jamf) have developed an innovative method for allowing computer and mobile device smart groups to figure out device membership based on users and groups from an identity provider (like Okta or Entra ID) or an LDAP service (like Active Directory).

Normally, figuring out user and group membership is not a capability of computer and mobile device smart groups but the method the Jamf @ Jamf folks developed leverages MDM configuration profiles to bridge that functionality gap in the following way:

  1. User is assigned an application with compliance policy in the organization’s identity provider.
  2. A Jamf @ Jamf automation system adds User Extension Attribute criteria to a username in scope of a group provided by the identity provider.
  3. A smart user group in Jamf Pro uses that criteria to populate group membership.
  4. The new smart user group is used to scope a configuration profile.

The configuration profile referenced in step 4 above is then deployed to devices that match the smart user group’s membership. Once the profile is deployed, the profile being installed on a device is criteria which can be used by computer and mobile device smart groups. This allows the profile to be the bridge functionality to connect users and user groups from an identity provider or an LDAP service.

In the post I linked to earlier, the configuration profiles created for this purpose are referred to as “dummy profiles”, which are in turn a reference to “dummy receipts”. Dummy receipts are a method for creating a receipt for an installer package installed by Jamf Pro, which likewise can be used as criteria which can be used by computer smart groups.

But what goes in that dummy profile? Ideally, it should be something that deploys no settings at all. The dummy profile’s existence on a device is enough to accomplish the goal of bridging the gap between user and device scoping and for the sake of causing no complications, the profile should exist on the device and otherwise do nothing. Meanwhile, this should be an approach which can be used on all Apple platforms so we need something which can be deployed to all Apple platforms.

After thinking about this for a bit and discussing it with colleagues, it looks like the best way to accomplish this is to build a configuration profile with the following characteristics:

  1. Profile with certificate payload
  2. Certificate payload should have the following:
  • Self-signed certificate’s public key
  • Certificate lifespan should be set to an extended period of time, to allow the use of the profile over a long period of time without worrying about the certificate expiring.

The reason to use a self-signed certificate’s public key is that a certificate can only be used for something if you have both the public and private key available. Without the private key being available at some point in the communication process to authenticate the public key as being valid, the public key is effectively useless.

In this case, that’s exactly what we want – we want something useless in the profile’s certificate payload because something useless can’t be used! Using this approach will mean that our configuration profile will deploy no settings to a Mac or mobile device, and a malicious third party won’t be able to use the certificate either because only the public key for it will be available. For more details, please see below the jump.

To assist with creating the self-signed certificate’s public key for our dummy profile’s certificate payload, I’ve written a script which does the following:

1. Generates a self-signed SSL certificate’s public key and associated private key, where the script’s default settings are to create a self-signed certificate with the following characteristics:

  • Certificate subject name is set to a UUID value.
  • Certificate key is set to use a 4096-bit RSA key
  • Certificate lifespan is set to 3652 days.

2. If the self-signed SSL certificate’s public key and private key are successfully created, script displays a message listing public key certificate name with a .cer file extension and the certificate public key’s location on the filesystem.

3. If the self-signed SSL certificate’s public key and private key are not successfully created, script displays an error message.

Note: Both the RSA key bit strength and lifespan are set using variables in the script, so these default settings can be adjusted as needed.

The private keys created by this script are completely disposable. For this purpose, we only want the public keys created by this script because we want a certificate payload which is functionally useless for use with Jamf Pro dummy configuration profiles.

A successful run of the script should produce output similar to that shown below:


username@computername % /path/to/create_certificate_public_keys_for_dummy_profile_certificate_payload.sh
Creating self-signed certificate with 4096 bit RSA key and a lifespan of 3652 days.
Generating a 4096 bit RSA private key
…………………………………………………..++++
…………………………………………………………………………………………….++++
writing new private key to '/var/folders/bq/d25fcnnj74j2gd8cnkhjmlqh0000gp/T/tmp.qkbeMzYTIY/2E69ABC8-3B5C-4F8F-ACE9-BAAAE592BF1C.key'
—–
Self-signed certificate successfully generated.
Self-signed certificate public key name: 2E69ABC8-3B5C-4F8F-ACE9-BAAAE592BF1C.cer
Self-signed certificate public key location: /var/folders/bq/d25fcnnj74j2gd8cnkhjmlqh0000gp/T/tmp.E45hx0xaW2/2E69ABC8-3B5C-4F8F-ACE9-BAAAE592BF1C.cer
username@computername %

view raw

gistfile1.txt

hosted with ❤ by GitHub

Once the public key is created, a new Jamf Pro configuration profile can be created. For this example, I’m setting up a new dummy configuration profile named Advertising Department Software Test Group which will be deployed to Macs.

As part of creating the profile, I’m selecting the Certificate payload option and uploading a certificate public key file created by my script. In this case, the public key file is named 2E69ABC8-3B5C-4F8F-ACE9-BAAAE592BF1C.cer.

Once the public key is uploaded, you will need to set a display name.

In this case, I’m choosing 2E69ABC8-3B5C-4F8F-ACE9-BAAAE592BF1C, which matches the subject name of the certificate.

In the certificate options, uncheck the following options:

  • Allow all apps access
  • Allow export from keychain

Both settings refer to the certificate’s private key (which is not being provided with the public key), but not allowing these options for certificates when you don’t have to is a good security-focused habit to cultivate.

Once the public key is uploaded and all the other choices you want are made for the profile, the profile should look like this:

Once deployed to a Mac, the profile should look like this in this example:

For this example, in Keychain Access.app you should see that a certificate named 2E69ABC8-3B5C-4F8F-ACE9-BAAAE592BF1C has been added to the System keychain as a self-signed root certificate without a private key associated with it.

Once the configuration profile is deployed, you can use the profile as part of a device smart group’s criteria.

Now you can apply whatever user-focused criteria you want to the Advertising Department Software Test Group configuration profile’s scoping and the device smart group’s membership will update to only include those devices with the Advertising Department Software Test Group configuration profile installed on them.

The script referenced above is available below, and also on GitHub via the following link:

https://github.com/rtrouton/rtrouton_scripts/tree/main/rtrouton_scripts/Casper_Scripts/create_certificate_public_keys_for_dummy_profile_certificate_payload


#!/bin/bash
# This script is used for creating SSL certificate public keys for use with Jamf Pro
# dummy profiles. The SSL certificate public keys created by this script by default
# have the following characteristics:
#
# * Self-signed
# * RSA 4096-bit key
# * Good for ten years (3652 days)
public_certificate_directory=$(mktemp -d)
private_key_directory=$(mktemp -d)
certificate_name=$(uuidgen)
certificate_bit="4096"
certificate_lifespan="3652"
# Generate a self-signed SSL certificate's public key and associated private key, where
# the script's default settings are to use a 4096-bit RSA key and a lifespan of 3652
# days. The private keys and public keys are stored in separate directories to help avoid
# confusion about which is which for script users who are new to using certificates.
#
# The private keys created by this script are completely disposable. For this purpose,
# we only want the public keys created by this script because we want a certificate payload
# for Jamf Pro dummy profiles which is functionally useless.
echo "Creating self-signed certificate with $certificate_bit bit RSA key and a lifespan of $certificate_lifespan days."
/usr/bin/openssl req -x509 -newkey rsa:"$certificate_bit" -sha256 -days "$certificate_lifespan" -nodes -keyout "$private_key_directory/$certificate_name.key" -out "$public_certificate_directory/$certificate_name.cer" -subj "/CN=$certificate_name"
# If the self-signed SSL certificate's public key and private key are successfully
# created, script displays a message listing public key certificate name with a
# .cer file extension and the certificate public key's location on the filesystem.
if [[ -f "$public_certificate_directory/$certificate_name.cer" ]] && [[ -f "$private_key_directory/$certificate_name.key" ]]; then
echo "Self-signed certificate successfully generated."
echo "Self-signed certificate public key name: $certificate_name.cer"
echo "Self-signed certificate public key location: $public_certificate_directory/$certificate_name.cer"
else
echo "ERROR: Self-signed certificate creation failed."
fi

Detecting via Jamf Pro if a Mac is being issued an IPv4 or IPv6 address

I assisted a colleague recently with an interesting request – how to detect if a Mac is only being issued an IPv6 address? In this instance, the use case was for when a Mac is on a network where only IPv6 addresses are being issued by DHCP (so no IPv4 addresses are available.)

The idea was to get a Yes or No answer for whether any of the Mac’s network interfaces were being issued an IPv4 address, where Yes meant that at least one network interface had an IPv4 IP address and No if none of the network interfaces had an IPv4 IP address.

After some research and discussion with colleagues in the Mac Admins Slack, this information was available via the system_profiler command line tool, using the SPNetworkDataType datatype. You can parse the output from the system_profiler tool using the following command to get a count of how many IPv4 addresses are in use by the various network interfaces on a Mac:


/usr/sbin/system_profiler SPNetworkDataType | /usr/bin/grep -c "IPv4 Addresses:"

view raw

gistfile1.txt

hosted with ❤ by GitHub

 

For example, if your Mac has IPv4 IP addresses assigned to both Ethernet and Wi-Fi, you should see output like this to show that your Mac has two assigned IPv4 addresses (one for Ethernet and one for Wi-Fi):


username@computername ~ % /usr/sbin/system_profiler SPNetworkDataType | /usr/bin/grep -c "IPv4 Addresses:"
2
username@computername ~ %

view raw

gistfile1.txt

hosted with ❤ by GitHub

 

This same approach works for IPv6 addresses, where you can parse the output from system_profiler using the following command to get a count of how many IPv6 addresses are in use by the various network interfaces on a Mac:


/usr/sbin/system_profiler SPNetworkDataType | /usr/bin/grep -c "IPv6 Addresses:"

view raw

gistfile1.txt

hosted with ❤ by GitHub

 

For example, if your Mac has no IPv6 IP addresses assigned to any network interfaces, you should see output like this to show that your Mac has no assigned IPv6 addresses:


username@computername ~ % /usr/sbin/system_profiler SPNetworkDataType | /usr/bin/grep -c "IPv6 Addresses:"
0
username@computername ~ %

view raw

gistfile1.txt

hosted with ❤ by GitHub

 

I’ve used this technique to create Jamf Pro Extension Attributes which can help figure out if a particular Mac has IPv4 or IPv6 addresses assigned to it, which can help in the use case I discussed earlier to help figure out if no IPv4 or no IPv6 addresses are available to a particular Mac. For more details, please see below the jump.

 

 

I’ve written two Extension Attributes, one for detecting IPv4 addresses and the other for IPv6 addresses. Here’s how they work:

Detects if an IPv4 / IPv6 network address is being used on a Mac. It returns the value below if one or more IPv4 / IPv6 addresses are detected on the Mac’s various network interfaces.

1

In all other cases, the value below is returned:

0

 

The Extension Attribute’s returned value ( 1 or 0 ) can then be used as Jamf Pro smart group criteria.

 

IPv4 version of the Extension Attribute:

https://github.com/rtrouton/rtrouton_scripts/tree/main/rtrouton_scripts/Casper_Extension_Attributes/check_for_IPv4_address_used_on_Mac

IPv4 Jamf Pro Extension Attribute Setup.

 

 

IPv6 version of the extension attribute:

https://github.com/rtrouton/rtrouton_scripts/tree/main/rtrouton_scripts/Casper_Extension_Attributes/check_for_IPv6_address_used_on_Mac

IPv6 Jamf Pro Extension Attribute Setup.