Pult Presence Docs
Pult AgentMDM Deployment

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 .pkg install.
  • 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 .pkg installs 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 0

What it does:

  1. Detects the logged-in console user (refuses to run when nobody is signed in).
  2. Delivers the token using the configured TOKEN_DELIVERY method:
    • 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: calls pult-agent --bootstrap-token as the console user, writing directly to Keychain, then signals any running agent to reload via --reload-bootstrap-token.
  3. 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

Troubleshooting

IssueSolution
Token file not consumed after installConfirm 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 barConfirm 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 DashboardCheck 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

On this page