Working in IT and Security is ever-evolving. You are always being introduced to new problems, daunting projects, and emerging threats. Fortunately, at times you come across a way to simplify your life.
In my previous SentinelOne posts (Here and Here), I walked you through how to use Kandji to deploy SentinelOne and a few profiles. It was an easy enough process but after a recent chat with a fellow IT Guru (thanks Campbell) I was able to make the process a little easier to manage and maintain.
So, are you ready to make SentinelOne deployments and upkeep fade into the background in your already busy life? Me too, let’s jump in!
What changed?
The major changes to the process are as follows:
- Removed the pre and post install scripts.
- Changed Install process from Zip File to Package Installer.
- Moved the SentinelOne Site/Group Token into a custom profile.
Step 1: Creating and Uploading the Configuration Profiles
Before installing SentinelOne, you need to deploy six essential configuration profiles to each Mac device:
- S1 - Service Management
- S1 - Full Disk Access
- S1 - Network Filtering
- S1 - Network Monitoring
- S1 - Notifications
- S1 - Token
These profiles grant SentinelOne the permissions it needs to monitor and protect your devices effectively. Skipping this step will most likely lead to issues down the road. For instance, if you don’t have the Network Filtering and Monitoring profiles installed prior to installing the SentinelOne PKG, you’ll most likely run into connectivity issues on the device and/or annoying pop-ups.
Below are the XML contents for each profile. Each one can be found on GitHub where all you’ll need to do is download them and make a minor change for the Token profile prior to uplodading into Kandji. If you prefer the manual path, just copy and paste these into a text document, save them as a .mobileconfig and upload them.
1. S1 - Service Management.mobileconfig
This profile manages components that run at startup, ensuring SentinelOne’s services are not removed.
<?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>PayloadContent</key> <array> <dict> <key>PayloadIdentifier</key> <string>com.apple.servicemanagement.E01FDD5D-6953-4F89-AE9C-98EC6AF31483</string> <key>PayloadType</key> <string>com.apple.servicemanagement</string> <key>PayloadUUID</key> <string>E01FDD5D-6953-4F89-AE9C-98EC6AF31483</string> <key>Rules</key> <array> <dict> <key>Comment</key> <string>Prevent removal of SentinelOne Launch Agents and Launch Daemons</string> <key>RuleType</key> <string>LabelPrefix</string> <key>RuleValue</key> <string>com.sentinelone.</string> </dict> <dict> <key>Comment</key> <string>Prevent removal of SentinelOne Launch Agents and Launch Daemons</string> <key>RuleType</key> <string>BundleIdentifierPrefix</string> <key>RuleValue</key> <string>com.sentinelone.</string> </dict> </array> </dict> </array> <key>PayloadDescription</key> <string>Manage components that run at start up</string> <key>PayloadDisplayName</key> <string>S1 - Service Management</string> <key>PayloadIdentifier</key> <string>com.kandji.profile.custom.171d06c6-d781-4756-9371-fbd5f91b23e5</string> <key>PayloadOrganization</key> <string>Sentinel Labs, Inc.</string> <key>PayloadRemovalDisallowed</key> <true/> <key>PayloadScope</key> <string>System</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>998ba1a8-d0f9-5b57-bb75-967dc12f9799</string> <key>PayloadVersion</key> <integer>1</integer></dict></plist>
2. S1 - Full Disk Access.mobileconfig
This profile grants SentinelOne full disk access.
<?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>PayloadContent</key> <array> <dict> <key>PayloadDescription</key> <string></string> <key>PayloadDisplayName</key> <string>Privacy Preferences Policy Control</string> <key>PayloadIdentifier</key> <string>236FFBB3-159D-4A5F-B146-AAA7BBA11FF0</string> <key>PayloadOrganization</key> <string>Your Company</string> <key>PayloadType</key> <string>com.apple.TCC.configuration-profile-policy</string> <key>PayloadUUID</key> <string>236FFBB3-159D-4A5F-B146-AAA7BBA11FF0</string> <key>PayloadVersion</key> <integer>1</integer> <key>Services</key> <dict> <key>SystemPolicyAllFiles</key> <array> <dict> <key>Allowed</key> <integer>1</integer> <key>CodeRequirement</key> <string>anchor apple generic and identifier "com.sentinelone.sentineld" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "4AYE5J54KN")</string> <key>Identifier</key> <string>com.sentinelone.sentineld</string> <key>IdentifierType</key> <string>bundleID</string> <key>StaticCode</key> <integer>0</integer> </dict> <dict> <key>Allowed</key> <integer>1</integer> <key>CodeRequirement</key> <string>anchor apple generic and identifier "com.sentinelone.sentineld-helper" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "4AYE5J54KN")</string> <key>Identifier</key> <string>com.sentinelone.sentineld-helper</string> <key>IdentifierType</key> <string>bundleID</string> <key>StaticCode</key> <integer>0</integer> </dict> <dict> <key>Allowed</key> <integer>1</integer> <key>CodeRequirement</key> <string>anchor apple generic and identifier "com.sentinelone.sentineld-shell" and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "4AYE5J54KN")</string> <key>Identifier</key> <string>com.sentinelone.sentineld-shell</string> <key>IdentifierType</key> <string>bundleID</string> <key>StaticCode</key> <integer>0</integer> </dict> </array> </dict> </dict> </array> <key>PayloadDescription</key> <string>Provides access to all disk to Sentinel One processes</string> <key>PayloadDisplayName</key> <string>S1 - Full Disk Access</string> <key>PayloadIdentifier</key> <string>com.kandji.profile.custom.c8e2c703-2228-4b77-a251-b488b4e36104</string> <key>PayloadOrganization</key> <string>Sentinel Labs, Inc.</string> <key>PayloadRemovalDisallowed</key> <true/> <key>PayloadScope</key> <string>System</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>d7da0976-c4e7-5a82-8c3e-c3853cb51a85</string> <key>PayloadVersion</key> <integer>1</integer></dict></plist>
3. S1 - Network Filtering.mobileconfig
This profile authorizes automatic validation of SentinelOne network filtering.
<?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>PayloadContent</key> <array> <dict> <key>FilterDataProviderBundleIdentifier</key> <string>com.sentinelone.network-monitoring</string> <key>FilterDataProviderDesignatedRequirement</key> <string>identifier "com.sentinelone.network-monitoring" and anchor apple generic and (certificate leaf[field.1.2.840.113635.100.6.1.9] /* exists */ or certificate 1[field.1.2.840.113635.100.6.2.6] /* exists */ and certificate leaf[field.1.2.840.113635.100.6.1.13] /* exists */ and certificate leaf[subject.OU] = "4AYE5J54KN")</string> <key>FilterGrade</key> <string>firewall</string> <key>FilterPackets</key> <false/> <key>FilterSockets</key> <true/> <key>FilterType</key> <string>Plugin</string> <key>PayloadDisplayName</key> <string>Web Content Filter Payload</string> <key>PayloadIdentifier</key> <string>14DDD990-E2D8-4DD1-8CC6-72FEFB5F252B</string> <key>PayloadOrganization</key> <string>JAMF Software</string> <key>PayloadType</key> <string>com.apple.webcontent-filter</string> <key>PayloadUUID</key> <string>14DDD990-E2D8-4DD1-8CC6-72FEFB5F252B</string> <key>PayloadVersion</key> <integer>1</integer> <key>PluginBundleID</key> <string>com.sentinelone.extensions-wrapper</string> <key>UserDefinedName</key> <string>SentinelOne Extensions</string> </dict> </array> <key>PayloadDescription</key> <string>Authorizes SentinelOne Network Filter automatic validation.</string> <key>PayloadDisplayName</key> <string>S1 - Network Filtering</string> <key>PayloadIdentifier</key> <string>com.kandji.profile.custom.b2733b15-44c2-41e0-a958-08dc2086b1d4</string> <key>PayloadOrganization</key> <string>Sentinel Labs, Inc.</string> <key>PayloadRemovalDisallowed</key> <true/> <key>PayloadScope</key> <string>System</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>c44d89ec-1790-5c05-a407-590166aeeb68</string> <key>PayloadVersion</key> <integer>1</integer></dict></plist>
4. S1 - Network Monitoring.mobileconfig
This profile enables automatic loading of SentinelOne’s system extension for network monitoring.
NOTE: It is possible to replace this profile within Kandji by using a System Extension versus a custom 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"><plist version="1.0"><dict> <key>PayloadContent</key> <array> <dict> <key>AllowUserOverrides</key> <true/> <key>AllowedSystemExtensions</key> <dict> <key>4AYE5J54KN</key> <array> <string>com.sentinelone.network-monitoring</string> </array> </dict> <key>PayloadDescription</key> <string></string> <key>PayloadDisplayName</key> <string>System Extensions</string> <key>PayloadIdentifier</key> <string>1BDD5153-6C81-4E0F-B409-1C321FF5E251</string> <key>PayloadOrganization</key> <string>Gete.Net Consulting</string> <key>PayloadType</key> <string>com.apple.system-extension-policy</string> <key>PayloadUUID</key> <string>1BDD5153-6C81-4E0F-B409-1C321FF5E251</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </array> <key>PayloadDescription</key> <string>Enables automatic loading of SentinelOne System Extension.</string> <key>PayloadDisplayName</key> <string>S1 - Network Monitoring</string> <key>PayloadIdentifier</key> <string>com.kandji.profile.custom.91444b37-8d15-46e9-a689-a52d526671c9</string> <key>PayloadOrganization</key> <string>Sentinel Labs, Inc.</string> <key>PayloadRemovalDisallowed</key> <true/> <key>PayloadScope</key> <string>System</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>e392826e-b758-5e39-959a-ed4f813ab1d9</string> <key>PayloadVersion</key> <integer>1</integer></dict></plist>
5. S1 - Notifications.mobileconfig
Lastly, this profile forces acceptance of all notifications from the SentinelOne agent.
<?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>PayloadContent</key> <array> <dict> <key>NotificationSettings</key> <array> <dict> <key>AlertType</key> <integer>1</integer> <key>BadgesEnabled</key> <true/> <key>BundleIdentifier</key> <string>com.sentinelone.SentinelAgent</string> <key>CriticalAlertEnabled</key> <true/> <key>GroupingType</key> <integer>0</integer> <key>NotificationsEnabled</key> <true/> <key>ShowInCarPlay</key> <false/> <key>ShowInLockScreen</key> <true/> <key>ShowInNotificationCenter</key> <true/> <key>SoundsEnabled</key> <true/> </dict> </array> <key>PayloadDisplayName</key> <string>Notifications</string> <key>PayloadIdentifier</key> <string>com.apple.notificationsettings.406D4B22-BE3A-4361-8C7B-B8ECE25BC8D6</string> <key>PayloadType</key> <string>com.apple.notificationsettings</string> <key>PayloadUUID</key> <string>2EA2BDB3-83CE-40DB-B3DF-33BD0094F0DF</string> <key>PayloadVersion</key> <integer>1</integer> </dict> </array> <key>PayloadDescription</key> <string>Forces notifications for SentinelOne Agent</string> <key>PayloadDisplayName</key> <string>S1 - Notifications</string> <key>PayloadEnabled</key> <true/> <key>PayloadIdentifier</key> <string>com.kandji.profile.custom.26783496-95e2-48d9-949b-d71a37181592</string> <key>PayloadOrganization</key> <string>Sentinel Labs, Inc.</string> <key>PayloadScope</key> <string>System</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>cbcf5c85-c136-5cbd-b69a-2ce35ffd00d3</string> <key>PayloadVersion</key> <integer>1</integer> <key>TargetDeviceType</key> <integer>5</integer></dict></plist>
6. S1 - Token.mobileconfig
Lastly, this profile forces acceptance of all notifications from the SentinelOne agent.
NOTE: You need to replace the string “SITE OR GROUP TOKEN HERE” in the xml to get this to work properly. You can get your Site or Group Token from the SentinelOne admin console.
Something to be mindful of with this method over the old method: This will make the Site or Group token viewable in plain text if someone were to open the profile in the System Settings app. Some may see this as a security risk. If you do, just refer back to my previous guides to inject the Token using a Pre-Install script that you can delete after the installation is complete. I plan on creating a method to encrypt the profile to prevent this but that is a ways off.
<?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>PayloadContent</key> <array> <dict> <key>PayloadType</key> <string>com.sentinelone.registration-token</string> <key>PayloadIdentifier</key> <string>1908502B-DFFE-43A8-ABEC-E0830251CB67</string> <key>PayloadUUID</key> <string>1908502B-DFFE-43A8-ABEC-E0830251CBF5</string> <key>S1InstallRegistrationToken</key> <string>SITE OR GROUP TOKEN HERE</string> </dict> </array> <key>PayloadDescription</key> <string>SentinelOne agent registration token</string> <key>PayloadDisplayName</key> <string>S1 - Token</string> <key>PayloadIdentifier</key> <string>CF822211-476A-47D6-BA6F-0A3333804A49</string> <key>PayloadOrganization</key> <string>SentinelOne</string> <key>PayloadRemovalDisallowed</key> <true/> <key>PayloadScope</key> <string>System</string> <key>PayloadType</key> <string>Configuration</string> <key>PayloadUUID</key> <string>1908502B-DFFE-43A8-ABEC-E0830251CB53</string> <key>PayloadVersion</key> <integer>1</integer></dict></plist>
Uploading Profiles to Kandji
Here’s how to get these profiles into Kandji:
- Upload to Kandji:
- Log in to your Kandji dashboard.
- Navigate to Library > Add New > Configuration Profile.
- Create and Upload each .mobileconfig file separately.
- Assign Profiles to Devices:
- Add the profiles to the relevant Blueprints or Assignment Maps.
- Ensure these profiles are deployed before installing SentinelOne.
Important Notes about Profiles
- Profiles Must Be Installed First: The audit script below will verify these profiles are properly installed. If they’re not installed, the SentinelOne installation won’t proceed.
- All-In-One Profile: There’s a combined profile on GitHub from Kandji, but it’s a little outdated and Kandji no longer has it publicly available. I haven’t tested it personally but I’ve received feedback it has worked for others. If you’d rather have a single profile handle this you can give it a try. I personally recommend using the profiles and scripts provided here for the most reliable results.
Step 2: Adding SentinelOne as a Custom App
We’ll be using Kandji’s Custom App Library item to deploy SentinelOne. The process involves:
- Creating your audit script: Ensures that all the profiles are properly installed prior to installing SentinelOne.
- Setting up the Custom App in Kandji: Configuring the installation details and uploading your packaged file.
- Add Custom app to your Assignment Maps or Blueprints.
1. Audit Script
The audit script checks if the required profiles are installed on the device. If they aren’t, the script exits, preventing the installation from proceeding. This ensures that SentinelOne doesn’t get installed without the necessary profiles, which could cause issues like loss of internet connectivity.
#!/bin/bash
# Array of required profilesREQUIRED_PROFILES=( "S1 - Full Disk Access" "S1 - Network Filtering" "S1 - Network Monitoring" "S1 - Notifications" "S1 - Service Management" "S1 - Token")
# Function to check if a profile is installedcheck_profile_installed() { local profile_name=$1 profiles_list=$(profiles -C -v | awk -F: '/attribute: name/{print $NF}')
if echo "$profiles_list" | grep -F -q "$profile_name"; then return 0 else return 1 fi}
# Check each required profilefor profile in "${REQUIRED_PROFILES[@]}"; do if ! check_profile_installed "$profile"; then echo "Error: $profile is not installed." exit 0 fidone
echo "All required profiles are installed. Proceeding to check for SentinelOne..."
# Check if SentinelOne is installedif [ -d "/Library/Sentinel/sentinel-agent.bundle/Contents/MacOS/SentinelAgent.app" ]; then echo "SentinelOne is installed." exit 0else echo "SentinelOne is not installed. Starting install process." exit 1fi
What This Script Does:
- Checks for the presence of the six required profiles.
- If any profiles are missing, it exits without proceeding.
- If all profiles are present, it checks if SentinelOne is already installed.
- If installed, it exits.
- If not installed, it triggers the installation.
2. Set Up the Custom App in Kandji
Let’s configure the Custom App in Kandji.
- Create a New Library Item:
- Go to your Kandji dashboard and add a new Custom App library item.
- Select Audit and Enforce for the installation method.
- Add the Audit Script from Step 1.
- Configure Installation Details:
- Deployment Type: Uncheck Self Service to deploy silently.
- Installation Type: Select Installer Package.
- Upload Latest SentinelOne pkg File: You can find the latest package inside the SentinelOne management console. Go to Endpoints > Packages > and grab the latest macOS version.
- Optional: Select Restart after successful install if you’d like to make sure everything is installed properly and reporting back to SentinelOne.
3. Deploying your Custom App
With everything set up:
- Test the Deployment: Before rolling it out company-wide, test on a few devices to ensure everything works smoothly. There should be no pop-ups for your end-users.
- Assign to your Assignment Maps or Blueprints: Once confirmed, add the Custom App and profiles to your desired Assignment Maps or Blueprints in Kandji.
- Final Tip: For Assignment Maps, I personally have most profiles installed in the first action “For All devices on this Blueprint” and then I have anotehr step that installs the Custom App. This gives me the flexibility to deploy a custom app to different departments and put them into Groups within SentinelOne using the Group Token versus Site Token. So my Engineers, who have specific exclusion rules in SentinelOne, have their own Custom App with a custom Profile for the token.
Final Thoughts
I developed this method because there didn’t seem to be a reliable guide that covered all the nuances of deploying SentinelOne with Kandji. By sharing my scripts and process, I hope to save you time and headaches.
Feedback Welcome!
If you have suggestions to improve these scripts or the deployment process, I’d love to hear them. Collaboration makes us all better at what we do.
Happy deploying!
If you found this guide helpful or have questions, don’t hesitate to reach out. Managing a Mac environment can be challenging, but with the right tools and shared knowledge, we can make it a smoother experience for everyone.
Thanks for reading (not) Your IT Guru! Make sure you Subscribe to my Substack to get the latest updates from me.