macOS doesn't provide a built-in way to block specific applications from running on a device. Using North Pole Security's Santa (formerly known as Google Santa) alongside Addigy's Smart Software, you can dynamically block any application by its Bundle ID across your fleet, and update that block list at any time without repackaging or reinstalling anything.
Overview
Santa is an open-source binary authorization tool for macOS, originally developed by Google and now maintained by North Pole Security (NPS). It runs as a system extension that can allow or block applications from launching based on criteria like Bundle ID, code signature, or SHA-256 hash.
Addigy deploys Santa as a Smart Software item. The installation script installs Santa, writes a configurable block list, and installs a LaunchDaemon that continuously checks the block list against installed applications and applies Santa rules automatically. This means you can add or remove blocked apps at any time just by updating the block list, without needing to push a new package.
This is useful for:
- Blocking known problematic, unlicensed, or non-compliant applications (e.g. consumer VPNs, unsanctioned chat apps, or specific browsers)
- Enforcing acceptable-use policies without relying on manual removal
- Responding quickly to a new app you need blocked across your fleet, without building a new workflow
Note: Google Santa was renamed North Pole Security Santa in 2024 when the project moved to independent maintenance. If you're currently running the legacy Google Santa package, see Migrating from Google Santa to North Pole Security Santa below before deploying new blocks.
Prerequisites
- The North Pole Security Santa
.pkginstaller, available from the official GitHub releases page - The Bundle ID(s) of the application(s) you want to block
How to Deploy Santa via Smart Software
Use this workflow to install Santa and begin blocking applications across a policy.
1. Download and deploy the required Custom Profiles
Santa needs a few macOS permissions to run without triggering user-facing security prompts. Download the .mobileconfig files attached at the bottom of this article (in the Custom Profiles section) and upload them to Addigy as Custom Profiles: How to Configure and Deploy a Custom Profile
Then, assign the Custom Profiles to the same policy as the Smart Software item for deployment.
2. Create the Smart Software Item
- Navigate to Catalog > Smart Software > New and give it a name (e.g.
Santa App Blocker). - Click Select File(s) and upload the Santa
.pkginstaller.
3. Add the Installation Script
Paste the below script into the Installation Command box and update the following variables:
- update
pkgFileto match the exact filename of the Santa.pkginstaller - update
downloadFolderto match the Download folder path shown under the Installation Command box
Add the Bundle IDs of the apps you want to block inside the blockList (APP BUNDLES TO BLOCK section), one per line. For example:
#!/bin/bash set -euo pipefail pkgFile=""
downloadFolder=""
pkgPath="${downloadFolder}/${pkgFile}"
santaDir="/Library/Addigy/Santa"
blockList="${santaDir}/block-list.txt"
blockScript="${santaDir}/santa-block.sh"
launchDaemon="/Library/LaunchDaemons/com.addigy.santa-blocker.plist"
logFile="/Library/Addigy/logs/santa-block.log" mkdir -p "${santaDir}" mkdir -p "/Library/Addigy/logs" # APP BUNDLES TO BLOCK
cat << "EOF" > "${blockList}"
app1.bundle.id
app2.bundle.id
app3.bundle.id
EOF /usr/sbin/installer -pkg "${pkgPath}" -target / cat << "EOF" > "${blockScript}" #!/bin/bash set -euo pipefail blockList="/Library/Addigy/Santa/block-list.txt" santactl="/usr/local/bin/santactl" log() { echo "$(date +"%d-%m-%Y %H:%M:%S") - $*" } block_app() { local bundleID="$1" local appPath="" local blockStatus="" local appName="" local sha256="" while IFS= read -r appPath; do [[ -z "${appPath}" ]] && continue [[ ! -e "${appPath}" ]] && continue blockStatus="$("${santactl}" fileinfo "${appPath}" --key "Rule" 2>/dev/null || true)" appName="$("${santactl}" fileinfo "${appPath}" --key "Bundle Name" 2>/dev/null || basename "${appPath}")" sha256="$("${santactl}" fileinfo "${appPath}" --key "SHA-256" 2>/dev/null || true)" [[ -z "${sha256}" ]] && { log "Could not get SHA-256 for ${bundleID} at ${appPath}" continue } if [[ "${blockStatus}" != Blocked* ]]; then log "Adding block rule for ${appName} (${bundleID}) at ${appPath}" "${santactl}" rule --block --sha256 "${sha256}" \ --message "${appName} (${bundleID}) is blocked and not allowed to run on this device." else log "${appName} (${bundleID}) is already blocked" fi pkill -9 -x "${appName}" 2>/dev/null || true done < <(mdfind "kMDItemCFBundleIdentifier == '${bundleID}'") } while IFS= read -r bundleID; do [[ -z "${bundleID}" ]] && continue block_app "${bundleID}" done < "${blockList}" EOF chmod 755 "${blockScript}" chown root:wheel "${blockScript}" cat << EOF > "${launchDaemon}" <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.addigy.santa-blocker</string> <key>ProgramArguments</key> <array> <string>/bin/bash</string> <string>${blockScript}</string> </array> <key>RunAtLoad</key> <true/> <key>StartInterval</key> <integer>60</integer> <key>StandardOutPath</key> <string>${logFile}</string> <key>StandardErrorPath</key> <string>${logFile}</string> </dict> </plist> EOF chmod 644 "${launchDaemon}" chown root:wheel "${launchDaemon}" launchctl bootout system "${launchDaemon}" 2>/dev/null || true launchctl bootstrap system "${launchDaemon}" launchctl enable system/com.addigy.santa-blocker launchctl kickstart -k system/com.addigy.santa-blocker touch "/Library/Addigy/.SantaInstalled"
4. Add the Condition Script
Expand the Condition for Install section and paste the following into the Advanced > Custom Conditional Commands box.
#!/bin/bash if [ ! -e "/Library/LaunchDaemons/com.addigy.santa-blocker.plist" ]; then echo "Missing /Library/LaunchDaemons/com.addigy.santa-blocker.plist" echo "Installing!" exit 0 fi if [ ! -e "/Library/Addigy/Santa/" ]; then echo "Missing /Library/Addigy/Santa/" echo "Installing!" exit 0 fi if [ ! -e "/usr/local/bin/santactl" ]; then echo "Missing /usr/local/bin/santactl" echo "Installing!" exit 0 fi checkFilePath="/Library/Addigy/.SantaInstalled" if ls "$checkFilePath" &> /dev/null; then echo "File $checkFilePath exists" else echo "File $checkFilePath does not exist" exit 0 fi echo "Device does not need to install blocker" echo "Exiting!" exit 1
5. Add the Removal Script
Paste the following into the Removal Command box so unassigning the Smart Software item cleanly removes Santa's rules, block list, and LaunchDaemon.
#!/bin/bash
cp /var/db/santa/rules.db /tmp/santa-rules.db
IFS=$'\n'
for rules in $(sqlite3 /tmp/santa-rules.db 'select * from rules' | awk -F '|' '{print $1}'); do
/usr/local/bin/santactl rule --remove --identifier "$rules"
done
if [ -e "/Library/LaunchDaemons/com.addigy.santa-blocker.plist" ]; then
sudo launchctl unload "/Library/LaunchDaemons/com.addigy.santa-blocker.plist"
rm -f "/Library/LaunchDaemons/com.addigy.santa-blocker.plist"
fi
if [ -e "/Library/Addigy/Santa/" ]; then
rm -rf "/Library/Addigy/Santa/"
fi
rm -rf "/tmp/santa-rules.db"6. Test and Deploy
- Navigate to a test device's GoLive page. Deploy the Custom Profiles and Smart Software item to confirm it installs cleanly and the block list takes effect. Ensure Profiles are installed prior to the software item.
- Once validated, assign the required Custom Profiles (from step 1) and Smart Software item to your target policy or policies.
Once deployed, devices check the block list every 60 seconds and automatically force-quit and block any matching running applications. If users attempt to launch a blocked application, the following prompt will appear:
How to Add or Remove Blocked Apps
Because the block list lives in a separate file on disk, you don't need to repackage or reinstall Santa to change which apps are blocked. Instead, run one of the scripts below against your target devices: Creating and Running Scripts on Your Devices (Saved Scripts)
Add apps to the block list
Update the bundleIDs array with the Bundle ID(s) you want to add, one per line:
#!/bin/bash
# Add one or more bundle IDs to Santa's block list
bundleIDs=(
"net.whatsapp.WhatsApp"
"org.mozilla.firefox"
"org.videolan.vlc"
)
blockList="/Library/Addigy/Santa/block-list.txt"
mkdir -p "/Library/Addigy/Santa"
touch "$blockList"
for bundleID in "${bundleIDs[@]}"; do
if grep -qFx "$bundleID" "$blockList"; then
echo "$bundleID is already in $blockList"
else
echo "$bundleID" >> "$blockList"
echo "Added $bundleID to $blockList"
fi
doneRemove apps from the block list
Update the bundleIDs array with the Bundle ID(s) you want to remove:
#!/bin/bash
# Remove one or more bundle IDs from Santa's block list
bundleIDs=(
"net.whatsapp.WhatsApp"
"org.mozilla.firefox"
"org.videolan.vlc"
)
blockList="/Library/Addigy/Santa/block-list.txt"
santactl="/usr/local/bin/santactl"
if [[ ! -f "$blockList" ]]; then
echo "Block list not found: $blockList"
exit 1
fi
for bundleID in "${bundleIDs[@]}"; do
escapedBundleID="${bundleID//./\\.}"
if grep -qFx "$bundleID" "$blockList"; then
sed -i '' "/^${escapedBundleID}\$/d" "$blockList"
echo "Removed $bundleID from $blockList"
else
echo "$bundleID was not found in $blockList"
fi
foundApp=0
while IFS= read -r appPath; do
[[ -z "$appPath" ]] && continue
[[ ! -e "$appPath" ]] && continue
echo "Removing Santa rule for: $appPath"
"$santactl" rule --remove --path "$appPath"
foundApp=1
done < <(mdfind "kMDItemCFBundleIdentifier == '${bundleID}'")
if [[ "$foundApp" -eq 0 ]]; then
echo "No installed app found for bundle ID: $bundleID"
fi
doneNote: Removing a Bundle ID from the block list clears its Santa rule and stops future enforcement, but the existing LaunchDaemon will continue running to enforce whatever remains on the list.
Migrating from Google Santa to North Pole Security Santa
If you have devices still running the legacy Google Santa package, North Pole Security's installer supports an in-place migration designed to avoid a gap in enforcement. This is adapted from North Pole Security's official Migration guide.
1. Update your Custom Profiles
- Update your System Extension profile to allow both Google Santa's Team ID (
EQHXZ8M8AV) and North Pole Security's Team ID (ZMCG7MLDV9) at the same time. This dual-authorization is temporary but prevents Google Santa from blocking NPS Santa if both try to start simultaneously. - Deploy an updated PPPC profile that also grants Full Disk Access to NPS Santa.
- (Optional) Add a Team ID rule for
ZMCG7MLDV9directly in Google Santa (viasantactl ruleor your sync server) as an extra guarantee against conflicts.
Note: Apply these profile updates before installing the NPS Santa package. This avoids system extension authorization pop-ups on end-user devices.
2. Install NPS Santa alongside Google Santa
Deploy the North Pole Security Santa .pkg using the Smart Software item described above (or update your existing Smart Software item to point at the new package). NPS Santa installs in a dormant state and automatically watches for Google Santa's removal — it will not appear in systemextensionsctl list until Google Santa is gone.
3. Remove Google Santa
Once NPS Santa has installed successfully on a device:
- Remove Google Santa's Team ID from the allowed system extensions profile. This triggers Google Santa to unload automatically, and NPS Santa finishes loading within a few seconds.
Note: To minimize any gap in enforcement, confirm the NPS Santa installer has already run on a device before removing Google Santa from that device's allowed extensions list.
4. Verify the migration
Run the following on a migrated device to confirm NPS Santa is active and Google Santa has been cleared:
$ systemextensionsctl list 2 extension(s) --- com.apple.system_extension.endpoint_security enabled active teamID bundleID (version) name [state] EQHXZ8M8AV com.google.santa.daemon (2024.9/2024.9.674285143) santad [terminated waiting to uninstall on reboot] * * ZMCG7MLDV9 com.northpolesec.santa.daemon (2024.10/2024.10.49) santad [activated enabled]
The terminated Google Santa entry clears automatically on the device's next reboot. You can also confirm the running version with:
$ santactl version santad | 2025.3 (build 94, commit 63bc558d) santactl | 2025.3 (build 94, commit 63bc558d) SantaGUI | 2025.3 (build 94, commit 63bc558d)
Frequently Asked Questions
Do I need to rebuild my existing block list when migrating?
No. The block list file used by the Addigy Smart Software workflow (/Library/Addigy/Santa/block-list.txt) is independent of which Santa binary is installed. Your existing Bundle IDs continue to apply once NPS Santa takes over.
How do I find an application's Bundle ID?
Run osascript -e 'id of app "AppName"' in Terminal on a Mac with the app installed, or check the app's Info.plist file (CFBundleIdentifier key) inside its .app bundle.
How to Get the Team ID, Bundle ID, and Code Requirement
How do I confirm an app is actually being blocked on a device?
Run santactl fileinfo /path/to/App.app --key Rule on the device. A blocked app will show a Rule value starting with Blocked. You can also check /Library/Addigy/logs/santa-block.log for the blocker's activity.
Related Articles
- Smart Software Overview
- Creating Smart Software
- Overview: Conditions for Install (Condition Scripts)