macOS Deployment via Post-install Script
Deploy the Pult Agent on macOS without a wrapper .pkg, using a post-install script your MDM runs after the canonical .pkg.
This page describes how to deploy the Pult Agent on macOS for MDMs that support running a script
after a .pkg install (e.g. Kandji). It avoids the wrapper-build step from
Build the macOS MDM Package and lets you keep the
Pult-signed .pkg exactly as distributed.
For MDMs that don't run post-install scripts, build a wrapper .pkg instead -- see Build the
macOS MDM Package. For Jamf Pro specifically,
see Jamf Pro Deployment (macOS).
When to use this approach
- Your MDM supports per-policy post-install scripts in addition to
.pkginstall. - You prefer not to maintain a wrapper artifact alongside the canonical
.pkg. - The token must be rotated independently of the app install (the script can run on its own).
Prerequisites
- The canonical Pult Agent
.pkg(signed and notarized by Pult). See Installation for download links. - A bootstrap token generated in the Pult Dashboard.
- A macOS MDM with permissions to deploy
.pkginstalls and post-install scripts.
Step 1: Deploy the canonical .pkg
Upload the Pult Agent .pkg to your MDM and deploy it to target Macs as a standard package install.
No customization required -- the canonical .pkg extracts to /Applications/Pult Agent.app.
Step 2: Run the post-install script
Configure your MDM to run the following script as a post-install action (or as a separate policy
that runs after the .pkg install). Replace your-bootstrap-token-here with the token from your
Pult Dashboard.
#!/bin/bash
set -euo pipefail
BOOTSTRAP_TOKEN="your-bootstrap-token-here"
# How to deliver the token to the agent. Default "file_drop" is recommended.
# - "file_drop": write a token file under the console user's
# ~/Library/Application Support/com.pult.agent/. The Pult Agent
# watches that directory and consumes the file on launch. Works
# even when no user is logged in at script run time, as long
# as the user's home directory exists.
# - "cli": call `pult-agent --bootstrap-token` as the console user,
# writing directly to the user's Keychain. Requires an active,
# interactive user session at script run time.
TOKEN_DELIVERY="file_drop"
AGENT_PATH="/Applications/Pult Agent.app/Contents/MacOS/pult-agent"
APP_NAME="Pult Agent"
CONSOLE_USER="$(/usr/bin/stat -f%Su /dev/console)"
if [[ -z "${CONSOLE_USER}" || "${CONSOLE_USER}" == "root" ]]; then
echo "No interactive console user detected. Exiting (nothing to do)."
exit 1
fi
CONSOLE_UID="$(/usr/bin/id -u "${CONSOLE_USER}")"
deliver_via_file() {
local user_home
user_home="$(/usr/bin/dscl . -read "/Users/${CONSOLE_USER}" NFSHomeDirectory \
| /usr/bin/awk '{print $2}')"
local dir="${user_home}/Library/Application Support/com.pult.agent"
local file="${dir}/BOOTSTRAP_TOKEN"
/usr/bin/sudo -u "${CONSOLE_USER}" /bin/mkdir -p "${dir}"
/usr/bin/sudo -u "${CONSOLE_USER}" /usr/bin/tee "${file}" >/dev/null <<<"${BOOTSTRAP_TOKEN}"
/bin/chmod 0600 "${file}"
echo "[file_drop] token written to ${file}"
}
deliver_via_cli() {
if [[ ! -x "${AGENT_PATH}" ]]; then
echo "Agent binary not found or not executable: ${AGENT_PATH}"
exit 1
fi
/bin/launchctl asuser "${CONSOLE_UID}" \
/usr/bin/sudo -Hu "${CONSOLE_USER}" \
"${AGENT_PATH}" --bootstrap-token "${BOOTSTRAP_TOKEN}"
/bin/launchctl asuser "${CONSOLE_UID}" \
/usr/bin/sudo -Hu "${CONSOLE_USER}" \
"${AGENT_PATH}" --reload-bootstrap-token
echo "[cli] token written to Keychain via pult-agent --bootstrap-token"
}
case "${TOKEN_DELIVERY}" in
file_drop) deliver_via_file ;;
cli) deliver_via_cli ;;
*)
echo "unknown TOKEN_DELIVERY: ${TOKEN_DELIVERY}"
exit 1
;;
esac
# Best-effort: launch the agent in the console user's context so the token is
# consumed immediately. If the agent is already running, this is a no-op.
/bin/launchctl asuser "${CONSOLE_UID}" \
/usr/bin/sudo -Hu "${CONSOLE_USER}" /usr/bin/open -a "${APP_NAME}" || true
exit 0What it does:
- Detects the logged-in console user (refuses to run when nobody is signed in).
- Delivers the token using the configured
TOKEN_DELIVERYmethod:file_drop(default, recommended): writes a token file to the user's~/Library/Application Support/com.pult.agent/. The agent watches this directory and consumes the file on next launch.cli: callspult-agent --bootstrap-tokenas the console user, writing directly to Keychain, then signals any running agent to reload via--reload-bootstrap-token.
- Best-effort launches the agent so the token is consumed immediately (rather than waiting for next login).
launchctl asuser plus sudo -Hu puts the binary in the user's full session context (correct
HOME, Keychain access). See
Build the macOS MDM Package -- Step 2
for the rationale.
Updating the token later
Re-run the same script with a new BOOTSTRAP_TOKEN value. Both delivery modes handle in-place
rotation -- the running agent picks up the new token without a restart.
Next Steps
- Configure Managed Login Items so the agent auto-starts at login and users can't disable it.
- To redo enrollment on a test Mac, reset the agent's stored credentials -- see CLI reference -- Common compositions.
Troubleshooting
| Issue | Solution |
|---|---|
| Token file not consumed after install | Confirm a user is logged in. The agent reads the token only when running in user context. If installed at the login window, wait for the next login. |
| Agent doesn't appear in the menu bar | Confirm Pult Agent.app is at /Applications/Pult Agent.app. Launch manually with open -a "Pult Agent" to see if it starts. |
| Pending Device Request never appears in the Dashboard | Check the agent's logs in ~/Library/Logs/com.pult.agent/. Verify the bootstrap token hasn't expired in the Pult Dashboard. |
cli mode aborts with "No interactive console user" | The script requires a logged-in user. Either switch to TOKEN_DELIVERY="file_drop" (works pre-login) or schedule the script to run after first login. |
Last updated on May 13, 2026, 12:21 PM
In-Browser macOS MDM PKG Builder
Build the macOS MDM wrapper .pkg directly in your browser -- no Mac required.
Jamf Pro Deployment (macOS)
Deploy the Pult Agent on macOS via Jamf Pro using a wrapper .pkg, an Extension Attribute for version detection, and a Smart Group-scoped Policy for continuous compliance.