Apple enforcing stricter network security requirements for future versions of Apple’s platform operating systems

Apple released a new KBase article on April 21st 2026, where the intended audience is IT admins and device management service developers. (For device management service developers, these are the vendors and other folks who build MDM servers.) The KBase article is available via the link below:

https://support.apple.com/126655

For more details, please see below the jump.

The key parts of Apple’s guidance are the following:

When is it happening?

In future versions of Apple’s various platform operating systems, which include iOS, iPadOS, macOS, watchOS, tvOS, and visionOS, Apple is going to be enforcing stricter controls on Transport Layer Security (TLS) connections. (These connections may also be referred to as Secure Sockets Layer (SSL) connections, as SSL is the now-deprecated technology that TLS was built on.)

This change could come as soon as the next major operating system release, which would mean the following operating systems:

  • iOS 27
  • iPadOS 27
  • macOS 27
  • watchOS 27
  • tvOS 27
  • visionOS 27

This does not necessarily mean that this change will be happening once those future operating systems have been released, but Apple is saying that it may happen at that time or at a later point in the future.

What’s affected?

  • Mobile device management (MDM)
  • Declarative Device Management (DDM)
  • Automated Device Enrollment
  • Configuration profile installation
  • App installation, including enterprise app distribution
  • Software updates

What’s that all mean? If I’m interpreting it correctly, it means that the tighter controls on TLS connections are going to be for communication between Apple devices and the following:

  • MDM servers
  • Apple’s Automated Device Enrollment service (part of Apple Business and Apple School Manager)
  • Apple’s app deployment services
  • Apple’s software update service

Apple is also explicitly saying there will be some exceptions to these tighter security controls. These exceptions are:

For those not familiar with SCEP, SCEP servers are intermediaries that sit between a certificate authority which issues digital certificates and the devices which use those digital certificates. In many enterprise environments which issue digital certificates to devices, an MDM server communicates with a SCEP server to get digital certificates for the devices the MDM server is managing, then provides those certificates to the devices which the MDM server is managing by putting the certificate in a configuration profile, then delivering that configuration profile using an MDM command.

Meanwhile, content caching servers are Apple’s solution which allows one device on your network to download Apple updates once and then share them locally with other devices. If there is a content caching server active on your local network, it is effectively a local copy of Apple’s software update servers which is available on your local network and allows you to save bandwidth by having your devices get their updates from that local copy in place of each device individually downloading their updates over the Internet from Apple’s software update service.

I don’t know why these exceptions for SCEP and content caching servers have been made, but my assumption is that Apple examined what would be involved in making these two exceptions also have to comply with the new standards and concluded that it either wasn’t possible or operationally too difficult at this time.

What’s changing?

Affected servers and services must:

  • Support TLS 1.2 or later
  • Use ATS-compliant ciphersuites
  • Present valid certificates that meet ATS standards

OK, what’s all that mean? First, let’s talk about the requirement to enforce TLS 1.2 and later. TLS and the earlier SSL have gone through various versions, with cryptographic strength increasing and bugs being fixed in each new version. To summarize why Apple is requiring TLS 1.2 and later, it’s because older versions of TLS and the older SSL supported communicating using weaker encryption methods which are not supported in TLS 1.2 and later and were subject to vulnerabilities that TLS 1.2 and later are not vulnerable to. By mandating TLS 1.2 and later, Apple is closing off those vulnerabilities and weaker encryption methods by rejecting connections which continue to use these prior versions of SSL and TLS. For those who want to dig deeper into this topic, please see the links below:

https://www.cloudflare.com/learning/ssl/transport-layer-security-tls/
https://www.ncsc.gov.uk/guidance/using-tls-to-protect-data
https://blog.gigamon.com/2021/07/14/what-is-tls-1-2-and-why-should-you-still-care/
https://www.statuscake.com/kb/knowledge-base/why-you-should-still-use-tls1-2-and-not-just-tls1-3/

Next, what the heck is ATS? In this case, it’s App Transport Security (ATS). ATS is a network security feature developed by Apple for its platforms, which mandates that network connections meet certain standards or ATS blocks them. ATS has been used to secure network communication for apps and app extensions. Now with this advisory being published, it looks like Apple is now extending ATS to secure communication between devices and MDM servers along with Apple’s app deployment, Automated Device Enrollment and software update services. So what is ATS requiring?

First, ATS is checking the TLS certificate provided by an MDM server or Apple’s affected services. This certificate must meet the following requirements:

  • Have an intact digital signature (this tells ATS that the certificate hasn’t been tampered with.)
  • Be unexpired (this tells ATS that the certificate is still within the date range prior to the certificate expiring.)
  • Certificate’s subject name matches the DNS name of the server in question
  • Has a valid certificate chain (where ATS can verify that the certificate it’s examining was signed by another valid certificate, which may be signed by another valid certificate, and so on all the way back to a Certificate Authority (CA) which is itself trusted by the device.)

Once ATS has run these checks on the certificate, it then makes the following additional checks to verify the following:

  • The server certificate must be signed with either a Rivest-Shamir-Adleman (RSA) key of at least 2048 bits, or an Elliptic-Curve Cryptography (ECC) key of at least 256 bits.
  • The certificate must use the Secure Hash Algorithm 2 (SHA-2) with a digest length, sometimes called a fingerprint, of at least 256 bits (that is, SHA-256 or greater).
  • Data must be exchanged using either the AES-128 or the AES-256 symmetric cipher.
  • The link must support perfect forward secrecy (PFS) through Elliptic Curve Diffie-Hellman Ephemeral (ECDHE) key exchange.

What’s all this mean? Let’s break it down by each check:

  • Certificate must be signed with either an RSA key with a minimum key length of 2048 bits (greater lengths are possible) or ECC key with a minimum length of 256 bits (greater lengths are possible). RSA is an older algorithm, where a greater key length is needed to provide better security. In contrast, ECC is a newer encryption approach which is able to provide equivalent security with a shorter key length. (For perspective, a 256-bit ECC key is equivalent to a 3072-bit RSA key.)

Why are RSA 2048-bit and ECC 256-bit set as the minimums? It’s the difference between “reasonably secure against attack” and “could be successfully attacked and protected communications exposed.” While shorter key lengths like RSA 1024-bit have not been publicly verified to be breakable, it is possible that nation-state adversaries with the resources available to them could break RSA 1024-bit or shorter key lengths if given sufficient time and the motivation to do so. RSA 2048-bit and ECC 256-bit are still considered beyond that level of vulnerability as of this time.

  • Certificate must use the Secure Hash Algorithm 2 (SHA-2) with a digest length of at least 256 bits (that is, SHA-256 or greater).

This is referring to the hash algorithm used to sign the certificate. In this case, what is happening is that, as part of generating and signing the certificate, a hash is generated known as a certificate digest (also known as a fingerprint.) This is a unique value for every certificate, where a valid digest verifies the following:

    • The certificate hasn’t been tampered with.
    • The certificate is unique.

If anything in the certificate changes, the digest will change and the hash can no longer be successfully verified (which in turn means the certificate is now rejected as invalid.)

There have been several hashing algorithms used for certificates over the decades, with the SHA-2 family of hash functions producing digests of specific sizes:

    • SHA-256: Produces a digest which is 256-bit in output size
    • SHA-384: Produces a digest which is 384-bit in output size
    • SHA-512: Produces a digest which is 512-bit in output size

There is also the older SHA-1 hash algorithm, which produces digests of smaller size. SHA-1 has been successfully attacked and broken in practice, so it is no longer considered secure enough for securing communication.

  • Data must be exchanged using either the AES-128 or the AES-256 symmetric cipher.

What this means is that the data being sent and received must be protected while in transit by specific encryption algorithms. In this case, the specified encryption algorithm is the Advanced Encryption Standard (AES), where the 128 and 256 parts refer to the key length being used:

    • AES-128: Key size is 128 bits in length
    • AES-256: Key size is 256 bits in length
  • The link must support perfect forward secrecy (PFS) through Elliptic Curve Diffie-Hellman Ephemeral (ECDHE) key exchange.

This has several parts. First, there’s perfect forward secrecy (PFS). This is a security property that ensures that if secure communication was compromised by an attacker getting the private key of a certificate, they could only read the communication which occurred at the time they compromised the communication and afterwards. If the attacker had recorded previous communication from before they had compromised the private key, they would not be able to read that older traffic even though the attacker now has the private key of the certificate.

Next, there’s Elliptic Curve Diffie-Hellman Ephemeral (ECDHE) key exchange:

    • Elliptic Curve: This is using elliptic curve mathematics to provide stronger security using smaller key sizes.
    • Diffie-Hellman: This is a method that allows two parties to securely agree on a shared secret over an insecure channel, without ever transmitting the key itself.
    • Ephemeral: This means that the keys used for this communication are temporary, with a new key pair being created for each communication session.

When it all gets put together, this is saying the following:

  1. Every connection must generate a fresh, temporary key pair using elliptic curve math.
  2. Both parties use Elliptic Curve Diffie-Hellman Ephemeral key exchange (ECDHE) to agree on a shared session key without transmitting it between them.
  3. Once the session ends, the temporary key pair is thrown away.

Step three is what ensures perfect forward secrecy (PFS). Since the key pair used for communication is always both temporary and discarded after each communication session, the actual key pair used to secure communication would be gone forever and unavailable to an attacker which compromised the private key at a later point in time.

What’s the end result?

After going through all that, what’s the end result that Apple’s going for? The answer is that they’re trying to both maximize security while still maintaining compatibility with the majority of systems already out in the world. TLS 1.2 is not the latest TLS version, as TLS 1.3 is available and more secure than TLS 1.2.

However, TLS 1.3 is a relatively new version and may not be compatible with all the services that Apple’s devices may need to communicate with. In this case, setting TLS 1.2 as the minimum strikes a balance between network security and operational compatibility. Similar balancing acts are seen in the minimums Apple is setting for certificate signing and certificate digests, where stronger options are available but may have compatibility issues with existing services.

The task for us as IT admins and MDM developers is going to be auditing our systems and MDM solutions, then making updates where needed to ensure they meet Apple’s new security standards before Apple enables App Transport Security for connections to those services. By telling us now that it may come as soon as the next major release of Apple’s operating systems, Apple’s informing us that we may only have until Fall 2026, when we can expect Apple to release the next major operating system versions, to find and make the necessary changes.

Slides from the “Preparing for macOS Next” session at MacAD.UK 2026

For those who wanted a copy of my talk on preparing for new versions of macOS at the MacAD.UK 2026 conference, here are links to the slides in PDF and Keynote format.

PDF: https://tinyurl.com/macaduk2026pdf
Keynote: https://tinyurl.com/macaduk2026key

DUNS number no longer required to sign up for Apple Business in the United States

Apple Business, the successor service to Apple Business Manager (ABM), launched on April 14, 2026. With the new service came a number of changes, including a change to how you could sign up for Apple Business and verify your business.

Previously, Apple Business Manager had required a Data Universal Numbering System (DUNS) number, which are issued to businesses by Dun & Bradstreet (D&B), to be used to verify that the organization looking to set up an ABM instance was in fact a recognized business. Now the verification requirement has changed from using a DUNS number to using a variety of business identification methods on a per-country basis. For the United States, the following business identifier is listed:

  • Registration type: Federal Taxpayer Identification Number
  • Description: Number assigned by the United States government to identify a business, generally a corporation or partnership.

Taxpayer Identification Numbers (TIN) are assigned by the US Internal Revenue Service to both individuals and organizations. In the case of a business, the TIN for business entities is an Employer Identification Number (EIN).

Apple also references the use of an EIN as part of the instructions on how to verify your organization when signing up for a new Apple Business instance. A DUNS number is referenced in the same instructions, so it appears that while a DUNS number remains an acceptable verification method, it’s no longer the only way Apple accepts business verification.

Detecting installed Intel-based applications on macOS Tahoe

On macOS Tahoe 26.4.x and later, launching an Intel-based app on an Apple Silicon Mac will periodically result in a message similar to the following being displayed by the OS.

This message is part of Apple’s transition strategy for Intel-based apps over the course of macOS 26 and macOS 27. The Rosetta 2 support used to run Intel-based apps will continue in its current form on both macOS 26 and macOS 27, but there will be as-yet unspecified changes occurring beyond macOS 27. For more information on this transition, please see the Apple KBase article linked below:

Using Intel-based apps on a Mac with Apple silicon
https://support.apple.com/102527

To help identify if and where Intel-based applications have been installed on Apple Silicon Macs, you can use System Information.app‘s list of installed software to identify which installed applications show up with the following status:

  • Kind: Intel

To assist with automating this task, a script is available which uses the /usr/sbin/system_profiler command line tool to detect all Intel-based apps installed in /Applications, /Library or /usr/local and output the list to a logfile named intel_apps_installed.log which is stored in the /var/log directory. For more details, please see below the jump.

The script does the following:

1. Checks to see if the script is being run as root.
2. Checks to see if the designated log file is present and creates it if it isn’t.
3. Uses the /usr/sbin/system_profiler command line tool to pull the complete list of installed applications
4. Filters all applications that are not Intel-based applications.
5. Excludes all Intel-based applications that are not stored in one of the following locations or their included directories:

  • /Applications
  • /Library
  • /usr/local

6. Outputs the following output to the log:

If any Intel-based applications are found in /Applications, /Library or /usr/local, the path to the detected Intel-based application or applications are listed in the log:

/path/to/Intel_based_application_name_here.app

If no Intel-based applications are found in /Applications, /Library or /usr/local, the following is output to the log:

No Intel-based applications found in /Applications, /Library or /usr/local.

The script is available below and also on GitHub at the following address:

https://github.com/rtrouton/rtrouton_scripts/tree/master/rtrouton_scripts/detect_installed_intel_based_apps


#!/bin/bash
# Detect all Intel apps installed in /Applications, /Library
# or /usr/local and output list to logfile stored in /var/log.
intel_app_logfile="/var/log/intel_apps_installed.log"
ERROR=0
# this script must be run with root privileges
if [[ "$(/usr/bin/id -u)" -eq 0 ]]; then
# Create log file if not present
if [[ -f "$intel_app_logfile" ]]; then
echo "$intel_app_logfile found. Proceeding…"
else
echo "Creating $intel_app_logfile log. Proceeding…"
touch "$intel_app_logfile"
fi
# Get a list of all installed applications
intel_app_list=$(/usr/sbin/system_profiler SPApplicationsDataType)
if [[ -n "$intel_app_list" ]]; then
# get all non-64 Bit applications from the initial list
intel_app_list=$(echo "$intel_app_list" | /usr/bin/grep -A3 "Intel")
# filter out all applications in /Applications, /Library and /usr/local
intel_app_list=$(echo "$intel_app_list" | /usr/bin/grep -E "Location:[^/]*/(Applications|Library|usr/local)/")
# remove everything except the path
intel_app_list=$(echo "$intel_app_list" | /usr/bin/sed -n 's/.*Location:[[:space:]]*\(.*\)/\1/p')
if [[ -n "$intel_app_list" ]]; then
echo "$intel_app_list" > "$intel_app_logfile"
echo "List of detected Intel-based applications available in $intel_app_logfile"
else
echo "No Intel-based applications found in /Applications, /Library or /usr/local." > "$intel_app_logfile"
fi
fi
else
log "ERROR! You must be root in order to run this script!"
ERROR=1
fi
exit $ERROR

Disabling Rosetta awareness messages on macOS Tahoe

As part of Apple’s move from using Intel processors to Apple Silicon processors for all Mac models, Apple has announced a transition timeline for macOS’s Rosetta 2 translation environment. Rosetta 2 will continue in its current form on both macOS 26 and macOS 27, but there will be as-yet unspecified changes occurring beyond macOS 27.

As part of this transition process, as of macOS Tahoe 26.4 there is a new window that will be periodically displayed when apps which are Intel-based get launched on Apple Silicon Macs. For example, an earlier version of an Automator app I wrote named Show or Hide Desktop Icons.app is an Intel-based app.

On macOS 26.4 and later, launching this earlier version of the Show or Hide Desktop Icons app will periodically result in the following message being displayed by the OS.

Rosetta awareness window.

This new message may not be desirable to display in all Mac environments, so Apple has provided management options to prevent this message from being shown. For more details, please see below the jump.

The relevant preference domain and key values are below:

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

This setting can be managed by a configuration profile, where setting a boolean value of false will prevent the message from being displayed. Please see below for an example profile. This profile is also available via the following link:

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


<?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>A3A6F8B9-3A59-4D39-8569-FF38DA9A8C1F</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadIdentifier</key>
<string>A3A6F8B9-3A59-4D39-8569-FF38DA9A8C1F</string>
<key>PayloadDisplayName</key>
<string>Disable Rosetta Usage Awareness</string>
<key>PayloadDescription</key>
<string>Disables Rosetta Usage Awareness Dialog Window</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true />
<key>PayloadRemovalDisallowed</key>
<false />
<key>PayloadScope</key>
<string>System</string>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadDisplayName</key>
<string>Custom Settings</string>
<key>PayloadIdentifier</key>
<string>E36A3269-B3A0-42F1-B045-1DB4D27CE7A2</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadUUID</key>
<string>E36A3269-B3A0-42F1-B045-1DB4D27CE7A2</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadContent</key>
<dict>
<key>com.apple.applicationaccess</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>allowRosettaUsageAwareness</key>
<false />
</dict>
</dict>
</array>
</dict>
</dict>
</dict>
</array>
</dict>
</plist>

Managing automatic installation of Background Security Improvements for macOS using Blueprints in Jamf Pro

As a follow-up to my previous post for managing Background Security Improvements (BSIs) using Jamf Pro’s Blueprints, it looks like I misunderstood what one of the management options was actually doing. As part of my prior post, I had said that in order to set this:

  • Background Security Improvements will be automatically installed

You needed to do the following in the Blueprint’s Software Update Settings component:

1. Go to the Background Security Improvements section
2. Select the following options to apply the desired settings:

  • Background Security Improvements updates will be installed:
    • Select Allow for Background Security Improvements installation

That enables an installation option, but not the automatic installation option. For more details, please see below the jump.

What installation option is being enabled? As it turns out, what’s enabled is the logged-in user’s ability to manually select installing the BSI update. You can see this by setting the Background Security Improvements installation setting to Allow.

Once that’s been set and deployed to devices, look at System Settings: Privacy & Security: Background Security Improvements on a device that the setting has been deployed to. If there’s a BSI available to install, you’ll see it listed there along with an Install button.

Next, let’s set Background Security Improvements installation to Restrict and deploy the settings to devices.

Now when we look at System Settings: Privacy & Security: Background Security Improvements on a managed device, that section and its Install button have disappeared.

That means that the only install option available now is the automatic install option. Where’s that managed from? That is also managed in the Software Update Settings component, but in a different section. To set management for automatic installation of BSI updates:

1. Go to the Install Actions section
2. Select the following options to apply the desired settings:

  • Automatic installs of available security updates:
    • Select Always

When those settings are deployed to devices, you can go to System Settings: Privacy & Security: Background Security Improvements on a managed device and see that the Automatically Install setting is enabled and grayed out. There should also be a message that the setting is managed by your organization.

You can also disable automatic installation of BSIs, but a very important thing to be aware of is that the Automatic installs of available security updates setting is managing all background security updates for macOS, not only BSIs. This includes updates for Gatekeeper, XProtect and verifying the firmware that your Mac uses. Please keep that in mind if you want to disable automatic installs of BSIs.

If you’ve considered this information and still want to disable automatic installs of BSI updates, you can do so by using the following process:

1. Go to the Install Actions section
2. Select the following options to apply the desired settings:

  • Automatic installs of available security updates:
    • Select Never

When those settings are deployed to devices, you can go to System Settings: Privacy & Security: Background Security Improvements on a managed device and see that the Automatically Install setting is disabled and grayed out. There should also be a message that the setting is managed by your organization.

Managing Background Security Improvements for macOS using Blueprints in Jamf Pro

As part of Apple’s unveiling of Declarative Device Management (DDM) at WWDC 2023, Apple announced that DDM management included the ability to manage software updates. Jamf Pro’s Blueprints leverages this capability to support to support managing software updates, including Background Security Improvements. Let’s see how this works using the following software update configuration as an example:

  • Background Security Improvements will be automatically installed
  • Background Security Improvements can be removed

For more details, please see below the jump.

As of Jamf Pro 11.25.2, there is not a Blueprints template available for creating blueprints which manage software update settings so the blueprint will need to be configured manually. To do this, use the following procedure:

1. Log into Jamf Pro.

2. Select Blueprints

3. Click the Create blueprint button.

 

4. You should see an unconfigured Blueprint. Click where it says Untitled blueprint and provide a name.

For this example, I’m using Background Security Improvements Management Settings.

5. Scroll down in the list on the left-hand side of the browser window to locate the Software Update Settings component.

 

6. Click on the Software Update Settings component and drag the Software Update Settings component to the Components in this blueprint section.

Software update settings component click and drag.

 

7. Once added to the Components in this blueprint section, click anywhere on the Software Update Settings component to open it for editing.

8. At this point, you will see the software update management settings. From there, scroll down to the Background Security Improvements section and click the Configure button.

 

In the Background Security Improvements section, select the following options to apply the following desired settings:

  • Background Security Improvements updates will be installed:
    • Select Allow for Background Security Improvements installation
  • Background Security Improvements updates can be removed:
    • Select Allow for Background Security Improvements removal

Once all choices have been made and verified, click the Update button.

You should now see the following items set to Enabled:

  • Background Security Improvements installation
  • Background Security Improvements removal

 

9. Once all the settings choices have been made and verified, click the Save changes button.

 

10. At this point, you should have a blueprint which has all settings configured but where no target scope has been set. To scope this blueprint, go to the Scope section and click the arrow button.

 

11. Select a Jamf Pro smart or static group. For this example, I’m selecting a static group named Background Security Improvements Settings Deployment Group.

 

12. Once everything has been configured, click the Deploy button to deploy the changes to the Macs you want to manage.

 

18. Once deployed, the Blueprints screen in Jamf Pro should show the newly-created Background Security Improvements Management Settings Blueprint as being deployed.

 

You can also check on the managed device’s end by opening System Settings: General: Device Management, locating the MDM enrollment profile in the list of profiles and double-clicking on it.

When you scroll to the bottom of the enrollment profile’s window, you should see a Device Declarations section. If you’re deploying a software update configuration via Blueprints, you should see a Software Update listing for Software Update Settings in the Device Declarations section.

 

If you click on the Software Update Settings listing, you should see the details of what is being managed. In the case of our example where we are setting Background Security Improvements to be automatically installed and allowing the removal option, you should see the the following entries set to On:

  • Enable
  • Enable Removal

Deploying firewall management for macOS using Blueprints in Jamf Pro

As part of Apple’s unveiling of Declarative Device Management (DDM) at WWDC 2023, Apple announced that DDM management included the ability to deploy MDM configuration profiles using DDM as the delivery mechanism in place of using MDM to deliver the profiles. Jamf Pro’s Blueprints leverages this capability to support managing the settings for the built-in application firewall on macOS. Let’s see how this works with the following settings for the firewall:

  • Firewall enabled
  • Stealth mode enabled
  • User changes to the firewall disabled

For more details, please see below the jump.

As of Jamf Pro 11.25.2, there is not a Blueprints template available for creating blueprints which manage firewall settings so the blueprint will need to be configured manually. To do this, use the following procedure:

1. Log into Jamf Pro.

2. Select Blueprints.

3. Click the Create blueprint button.

4. You should see an unconfigured Blueprint. Click where it says Untitled blueprint and provide a name.

For this example, I’m using Firewall Management Settings.

5. Scroll down in the list on the left-hand side of the browser window to locate the Firewall component.

Note: The Firewall component is listed as being the Legacy Payload type. In Blueprints, a Legacy Payload type indicates that this is an MDM configuration profile being delivered via DDM.

6. Click on the Firewall component and drag the Firewall component to the Components in this blueprint section.

Firewall component click and drag.

7. Once added to the Components in this blueprint section, click anywhere on the Firewall component to open it for editing.

8. At this point, you will see the firewall management settings (with one exception which will be covered in following steps.) To apply the desired settings, select the following options and set them to True:

  • EnableFirewall
  • EnableStealthMode

9. Once all the settings choices have been made and verified, click the Save changes button.

10. The remaining setting (disabling the ability for the user to make changes to the firewall) is in the separate Security Preferences component.

Scroll down in the list on the left-hand side of the browser window to locate the Security Preferences component.

11. Click on the Security Preferences component and drag the Security Preferences component to the Components in this blueprint section.

Security preferences component click and drag.

12. Once added to the Components in this blueprint section, click anywhere on the Security Preferences component to open it for editing.

13. At this point, you will see the Security Preferences management settings. To apply the desired setting, select the following option and set it to True:

  • Do not allow firewall

14. Once all the settings choices have been made and verified, click the Save changes button.

15. At this point, you should have a blueprint which has all settings configured but where no target scope has been set. To scope this blueprint, go to the Scope section and click the arrow button.

16. Select a Jamf Pro smart or static group. For this example, I’m selecting a static group named Firewall Settings Deployment Group.

17. Once everything has been configured, click the Deploy button to deploy the changes to the Macs you want to manage.

18. Once deployed, the Blueprints screen in Jamf Pro should show the newly-created Firewall Management Settings Blueprint as being deployed.

You can also check on the managed device’s end by opening System Settings: General: Device Management, locating the MDM enrollment profile in the list of profiles and double-clicking on it. When you scroll to the bottom of the enrollment profile’s window, you should see a Device Declarations section.

If you’re deploying a legacy profile via Blueprints, you should see a Profiles section in Device Declarations. In the Profiles section, there is a listing with a name that matches the name of the blueprint which was deployed. In the case of our example, the listing shows Firewall Management Settings.

If you click on the Firewall Management Settings listing, you should see the details of what is being managed.

Note: The MDM profiles delivered via Blueprints are not signed. This is mentioned in the documentation available via the link below:

https://learn.jamf.com/en-US/bundle/jamf-pro-blueprints-configuration-guide/page/Blueprint_Builder.html

You can also verify that the firewall is turned on and not editable by the user by going to System Settings: Network: Firewall. It should display a message that the setting has been configured by a profile.

Using the Jamf Pro API to deploy installer packages using MDM commands

One of the capabilities of mobile device management (MDM) on macOS is that you can use MDM commands to deploy installer packages, via the InstallEnterpriseApplication MDM command. If you’re using Jamf Pro for your MDM management, the Jamf Pro API can be used to run this MDM command, allowing you to send out InstallEnterpriseApplication commands to deploy installer packages. For more details, please see below the jump.

The relevant Jamf Pro API endpoint is the v1/deploy-package endpoint. Here are the required API permissions for using it:

API permissions using user account authentication:

Jamf Pro Server Objects:

  • Computers: Read, Update

Jamf Pro Server Actions:

  • Send Computer Remote Command to Install Package
  • Send MDM command information in Jamf Pro API
  • View MDM command information in Jamf Pro API

API permissions using API client authentication:

  • Read Computers
  • Update Computers
  • Send Computer Remote Command to Install Package
  • Send MDM command information in Jamf Pro API
  • View MDM command information in Jamf Pro API

Installer packages deployed using this method would need to be signed and built as a distribution-style package. I have a blog post describing the details available via the link below:

https://derflounder.wordpress.com/2023/10/24/preparing-installer-packages-for-installation-using-mdm-commands/

If you look at the Jamf Pro API documentation available with Jamf Pro, using the v1/deploy-package Jamf Pro API endpoint to successfully deploy a package requires sending a JSON block containing a manifest for the package along with some additional information on whether or not the package is set to be managed and which devices to install it on. Let’s take a look at the essential components of this block, using an example provided as part of the Jamf API documentation:


{
"manifest": {
"url": "https://example.jamf.com/this/package&quot;,
"hash": "dcb02a41cd6d842943459a88c96a5f72",
"hashType": "MD5",
"displayImageUrl": "https://example.jamf.com/img/display/this/package.jpg&quot;,
"fullSizeImageUrl": "https://example.jamf.com/img/full/this/package.jpg&quot;,
"bundleId": "com.jamf.example",
"bundleVersion": "0.1.0",
"subtitle": "Subtitle",
"title": "Title",
"sizeInBytes": 12345
},
"installAsManaged": false,
"devices": [
1,
2,
3
],
"groupId": "1"
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

This has several parts, so let’s break it down by section:

Manifest:


"manifest": {
"url": "https://example.jamf.com/this/package&quot;,
"hash": "dcb02a41cd6d842943459a88c96a5f72",
"hashType": "MD5",
"displayImageUrl": "https://example.jamf.com/img/display/this/package.jpg&quot;,
"fullSizeImageUrl": "https://example.jamf.com/img/full/this/package.jpg&quot;,
"bundleId": "com.jamf.example",
"bundleVersion": "0.1.0",
"subtitle": "Subtitle",
"title": "Title",
"sizeInBytes": 12345
},

view raw

gistfile1.txt

hosted with ❤ by GitHub

This is providing the MDM command’s information about the package to be installed. Here are the essential parts you need to provide as part of the manifest:

  • URL: The installer package will need to be hosted on an available location which allows anonymous HTTPS downloads (i.e. downloading via HTTPS without requiring authentication.)
  • Hash: This is a unique, fixed-length string generated by running an file’s data (in this case an installer package) through a cryptographic algorithm like MD5 or SHA256.
  • Hash Type: This is the cryptographic algorithm being used. Either MD5 or SHA256 is supported.

Note: The hash type description must use capitalization. No lowercase letters allowed in this use case.

  • Bundle ID: For an installer package, this is the unique, reverse-DNS identifier (for example, com.example.app) used to identify macOS installer packages.
  • Bundle Version: For an installer package, this is the version of the installer package. Packages with the same package identifier are compared using this version, to determine if the package is an upgrade or downgrade.
  • Title: This is the title of the package being installed
  • Size in Bytes: This is the size in bytes of the installer package.

For more information on the topic of creating a manifest for installer packages deployed using the InstallEnterpriseApplication MDM command, please see the link below:

https://www.dersoldat.org/?p=1456

Next, there’s the choice to install as managed or not:


"installAsManaged": false,

view raw

gistfile1.txt

hosted with ❤ by GitHub

The installAsManaged configuration option defines if the installer package is defined as installing a managed app or not installing a managed app. For the most part, this defines whether or not the MDM would be able to uninstall the app following installation using the InstallEnterpriseApplication MDM command.

The default configuration for the InstallAsManaged configuration option is false, so unless you know you will need to define it as true, this configuration option does not need to be included as part of the API call.

For Mac admins, here are the considerations to keep in mind for this option:

installAsManaged = true:

  • The MDM server can install, track and remove the app installed by the installer package.

installAsManaged = false:

  • The MDM server is only deploying the installer package and does not track anything afterwards.

Of course, if you’re choosing to deploy an installer package, you need to define what devices you’re installing it on. That’s the next two parts of the configuration:

This allows you to define the individual Jamf Pro ID numbers of the devices you want to install on.


"devices": [
1,
2,
3
],

view raw

gistfile1.txt

hosted with ❤ by GitHub

This allows you to define the device static or smart group containing the devices you want to deploy the installer package to.


"groupId": "1"

view raw

gistfile1.txt

hosted with ❤ by GitHub

Here’s an example API command to install a package named MyGreatInstaller.pkg as unmanaged from an S3 bucket named 75d831079efb4d02ada44eed4f8ae093 on individual devices with Jamf Pro device IDs 102, 103 and 104:


/usr/bin/curl -s –header "Authorization: Bearer bearer_token_goes_here" –header "Content-type: application/json" "https://jamf.pro.server.goes.here/api/v1/deploy-package&quot; -X POST -d "{\"manifest\":{\"url\":\"https://75d831079efb4d02ada44eed4f8ae093.s3.us-east-1.amazonaws.com/MyGreatInstaller.pkg\",\"hash\":\"75c9ed772b6c31e705597014983a276b\",\"hashType\":\"MD5\",\"bundleId\":\"com.company.MyGreatInstaller\",\"bundleVersion\":\"2.0.1\",\"title\":\"MyGreatInstaller\",\"sizeInBytes\":20582383},\"devices\":[102,103,104]}"

view raw

gistfile1.txt

hosted with ❤ by GitHub

In this example, the JSON block being sent looks like this:


{
"manifest": {
"url": "https://75d831079efb4d02ada44eed4f8ae093.s3.us-east-1.amazonaws.com/MyGreatInstaller.pkg&quot;,
"hash": "75c9ed772b6c31e705597014983a276b",
"hashType": "MD5",
"bundleId": "com.company.MyGreatInstaller",
"bundleVersion": "2.0.1",
"title": "MyGreatInstaller",
"sizeInBytes": 20582383
},
"devices": [
102,
103,
104
]
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Here’s an example API command to install a package named MyGreatInstaller.pkg as unmanaged from an S3 bucket named 75d831079efb4d02ada44eed4f8ae093 on all devices in a Jamf Pro device group with Jamf Pro ID 37:


/usr/bin/curl -s –header "Authorization: Bearer $token_goes_here" –header "Content-type: application/json" "https://jamf.pro.server.goes.here/api/v1/deploy-package&quot; -X POST -d "{\"manifest\":{\"url\":\"https://75d831079efb4d02ada44eed4f8ae093.s3.us-east-1.amazonaws.com/MyGreatInstaller.pkg\",\"hash\":\"75c9ed772b6c31e705597014983a276b\",\"hashType\":\"MD5\",\"bundleId\":\"com.company.MyGreatInstaller\",\"bundleVersion\":\"2.0.1\",\"title\":\"MyGreatInstaller\",\"sizeInBytes\":20582383},\"groupId\":\"37\"}"

view raw

gistfile1.txt

hosted with ❤ by GitHub

In this example, the JSON block being sent looks like this:


{
"manifest": {
"url": "https://75d831079efb4d02ada44eed4f8ae093.s3.us-east-1.amazonaws.com/MyGreatInstaller.pkg&quot;,
"hash": "75c9ed772b6c31e705597014983a276b",
"hashType": "MD5",
"bundleId": "com.company.MyGreatInstaller",
"bundleVersion": "2.0.1",
"title": "MyGreatInstaller",
"sizeInBytes": 20582383
},
"groupId": "37"
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Once the API command is sent, there are two possible HTTP status codes which indicate the API command ran successfully:

  • HTTP 200
  • Meaning: Package deployment MDM command was successfully processed.
  • HTTP 202
  • Meaning: Package deployment MDM command was queued up for processing.

Here’s an example of a successful API response from an installer package deployment to a device with the Jamf Pro ID of 67:


{
"queuedCommands": [
{
"device": 67,
"commandUuid": "c30d945d-23ff-4d6d-be25-295af24d9a92"
}
],
"errors": []
}

view raw

gistfile1.txt

hosted with ❤ by GitHub

Using the Jamf Pro API to delete computers from Jamf Pro

Every so often, I need to delete one or multiple computers from a Jamf Pro server. This can be accomplished in the Jamf Pro admin console, but it can also be accomplished via the Jamf Pro API’s computers-inventory API endpoint. For more details, please see below the jump.

The API command to delete a computer inventory record from a Jamf Pro server should look similar to this:


/usr/bin/curl –header "Authorization: Bearer api_token_goes_here" -X DELETE "https://jamf.pro.server.here/api/v1/computers-inventory/jamf_pro_computer_ID_goes_here&quot;

view raw

gistfile1.txt

hosted with ❤ by GitHub

I was able to use the API information discussed above to create a script which:

  1. Deletes specified computer inventory records.
  2. Generates a report of the Macs whose computer inventory records were deleted.

The script is named Delete_Computers_From_Jamf_Pro.sh and is available via the link below:

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

The script is designed to take in a set of Jamf Pro ID numbers in a plaintext file, where the Jamf Pro ID numbers correspond the Macs you want to delete. The script can also accept one Jamf Pro ID number as input, if a plaintext file containing Jamf Pro ID numbers is not available.

Three items are required to use these scripts:

  • The URL of the appropriate Jamf Pro server.
  • The username of an account on the Jamf Pro server with sufficient privileges to delete computers from the Jamf Pro server.
  • The password for the relevant account on the Jamf Pro server.

Jamf Pro account privileges required by the Jamf Pro server account referenced above:

Jamf Pro Server Objects:

  • Computers: Read, Delete

If you want to delete multiple computers at once from Jamf Pro, you will also need to provide a plaintext file containing the Jamf Pro IDs of the computer you wish to delete. The plaintext file should look similar to this:


416462
842736
434703
338517
481915
596669

view raw

gistfile1.txt

hosted with ❤ by GitHub

Once the specified items are available, the scripts can be run using the following commands:

To use Delete_Computers_From_Jamf_Pro.sh to delete one computer:


/path/to/Delete_Computers_From_Jamf_Pro.sh

view raw

gistfile1.txt

hosted with ❤ by GitHub

To use Delete_Computers_From_Jamf_Pro.sh to delete multiple computers:


/path/to/Delete_Computers_From_Jamf_Pro.sh /path/to/plaintext_filename_here.txt

view raw

gistfile1.txt

hosted with ❤ by GitHub

When using Delete_Computers_From_Jamf_Pro.sh to delete one computer, you should see output that looks like this:


username@computername ~ % /Users/Shared/Delete_Computers_From_Jamf_Pro/Delete_Computers_From_Jamf_Pro_Status.sh
Please enter the relevant Jamf Pro ID number : 416462
Please enter your Jamf Pro server URL : https://jamf.pro.server.here
Please enter your Jamf Pro user account : username_goes_here
Please enter the password for the username_goes_here account:
Requested computers are being deleted from https://jamf.pro.server.here
Report on deleted computers is being generated. File location will appear below once ready.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/416462
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=416462.
Report on deleted Macs available here: /var/folders/ps/2_yw29gj711c9d7c5w5jhyv80000gp/T/tmp.rxRIIKNmx0.tsv
username@computername ~ %

As part of the script’s run, a report will be generated and you’ll be notified of where it is stored. The report will be in TSV format and appear similar to what’s shown below:



Jamf Pro ID Number Make Model Serial Number UDID Jamf Pro URL
416462 Apple MacBook Pro (16-inch, 2019) WD8JB8F49YS4 4D8CD419-1892-4CFE-8D18-D1DD53CC7970 https://jamf.pro.server.here/computers.html?id=416462

When using Delete_Computers_From_Jamf_Pro.sh to delete multiple computers, you should see output that looks like this:


username@computername ~ % /Users/Shared/Delete_Computers_From_Jamf_Pro/Delete_Computers_From_Jamf_Pro_Status.sh /Users/Shared/jamfpro_computer_ids.txt
Please enter your Jamf Pro server URL : https://jamf.pro.server.here
Please enter your Jamf Pro user account : username_goes_here
Please enter the password for the username_goes_here account:
Requested computers are being deleted from https://jamf.pro.server.here
Report on deleted computers is being generated. File location will appear below once ready.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/416462
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=416462.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/842736
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=842736.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/434703
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=434703.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/338517
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=338517.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/481915
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=481915.
curl -X DELETE https://jamf.pro.server.here/api/v1/computers-inventory/596669
Deleted the computer inventory record for https://jamf.pro.server.here/computers.html?id=596669.
Report on deleted Macs available here: /var/folders/ps/2_yw29gj711c9d7c5w5jhyv80000gp/T/tmp.eFStgTqa5l.tsv
username@computername ~ %

The corresponding report will appear similar to what’s shown below:



Jamf Pro ID Number Make Model Serial Number UDID Jamf Pro URL
416462 Apple MacBook Pro (16-inch, 2019) WD8JB8F49YS4 4D8CD419-1892-4CFE-8D18-D1DD53CC7970 https://jamf.pro.server.here/computers.html?id=416462
842736 Apple MacBook Pro (16-inch, 2019) R6JG7GYVNORW 904418F7-3695-44BF-9A00-74F5CF617377 https://jamf.pro.server.here/computers.html?id=842736
434703 Apple MacBook Pro (16-inch, 2019) FWPATJHWC92O 5CF418CE-3E46-481C-A171-7ACC9E1E2E7A https://jamf.pro.server.here/computers.html?id=434703
338517 Apple MacBook Pro (16-inch, 2019) CVZVJ8R55467 E82C6C63-5F49-4DD3-90A0-E01EC11F6954 https://jamf.pro.server.here/computers.html?id=338517
481915 Apple MacBook Pro (13-inch, M1, 2020) QL6ROPPB1SK5 CBC87B4C-28DA-417F-8790-411AF9F105AD https://jamf.pro.server.here/computers.html?id=481915
596669 Apple MacBook Pro (16-inch, 2021) CNA11CBMJSNI 72811617-8C97-4EB6-BC4B-B9FA9C87B259 https://jamf.pro.server.here/computers.html?id=596669

In addition to the scripts described above which use user accounts for authentication, there are also matching scripts which use API client authentication available on GitHub via the links above. If setting up an API client with limited rights, here are the required API role privileges for the API client on the Jamf Pro server:

  • Computers Read
  • Computers Delete