← Enterprise docs

Kandji deployment

A complete Kandji rollout requires:

  1. An enrollment Custom Profile (preference domain ai.preamp) carrying an enrollmentToken key. The managed .pkg’s preinstall aborts the install if this profile is not present, so it must be assigned and installed before the Custom App runs.
  2. A Custom App with a pre-install script that writes /etc/preamp/bootstrap.env, then installs preamp-managed-<version>.pkg.

A PPPC Library item granting Full Disk Access is optional. The default Claude backup path is user-owned and does not require Full Disk Access. Deploy the PPPC profile only if you want to pre-grant FDA defensively. See the PPPC profile guide.

An optional Custom Profile with preference domain ai.preamp also tunes runtime settings (schedule, full-backup interval, allow-uninstall, custom apiUrl); fold these keys into the enrollment profile from item 1.

Preinstall gate (v1.0.3): preamp-managed-1.0.3.pkg’s preinstall aborts unless /Library/Managed Preferences/ai.preamp.plist exists with an enrollmentToken key, failing with a generic “contact the software manufacturer” error. Assign the ai.preamp Custom Profile (with enrollmentToken set to your org token) and confirm it has installed before the Custom App runs. See the managed preferences reference.

Identity substitution: carry the assigned user’s email / fullname in a separate ai.preamp.identity Custom Profile and have the pre-install script read them via defaults read, rather than relying on variable substitution inside the script body. See the JAMF guide for the pattern; the same approach applies here.

Prerequisites

  • Preamp admin console access (to generate an enrollment token).
  • Kandji tenant with permission to create Blueprints and Library items.
  • The signed preamp-managed-<version>.pkg. See Package downloads for the URL and SHA-256 verification steps.
  • At least one verified domain for your org under app.preamp.ai → Settings → Domains. Without it, devices still back up but land in the per-org unattributed bucket on the Workforce tab instead of attributing to a real person.

Steps

  1. Generate an enrollment token in the Preamp admin console (https://app.preamp.ai/org/fleet/devices?tab=enrollment). Copy it immediately, the plaintext is shown only once.

  2. Create the enrollment Custom Profile. Library → Add new → Custom Profile with a preference domain ai.preamp payload carrying enrollmentToken (value: the token from step 1) and managed = true. This satisfies the preinstall gate. Assign it to the Blueprint and confirm it installs before the Custom App runs.

  3. Create the identity Custom Profile. Add a second Custom Profile with preference domain ai.preamp.identity carrying email and fullname, populated via Kandji’s assigned-user substitution variables. As with JAMF, substitution applies inside Configuration Profile payloads but not inside script bodies, so identity must be carried here rather than hard-coded in the pre-install script. Consult Kandji’s variable documentation for the exact token syntax in your tenant. The email must resolve to a verified-domain address for per-person attribution.

  4. Create the Custom App in Kandji. Library → Add new → Custom App. Upload preamp-managed-<version>.pkg. Set Install Type to Audit and Enforce. In the Pre-install script field, paste:

    #!/bin/bash
    set -euo pipefail
    
    IDENTITY_PLIST="/Library/Managed Preferences/ai.preamp.identity"
    
    TOK="REPLACE_WITH_ORG_TOKEN"
    
    # Read identity from the ai.preamp.identity Configuration Profile via
    # defaults read. Kandji does not substitute variables inside this script
    # body, so identity must come from the profile, not a hard-coded token.
    EM="$(/usr/bin/defaults read "$IDENTITY_PLIST" email 2>/dev/null || true)"
    NM="$(/usr/bin/defaults read "$IDENTITY_PLIST" fullname 2>/dev/null || true)"
    
    if [[ -z "$TOK" ]]; then
      echo "preamp bootstrap: org token is required" >&2
      exit 1
    fi
    
    mkdir -p /etc/preamp
    chmod 0700 /etc/preamp
    
    umask 077
    {
      printf 'PREAMP_ORG_TOKEN=%s\n' "$TOK"
      printf 'PREAMP_USER_EMAIL=%s\n' "$EM"
      printf 'PREAMP_USER_NAME=%s\n'  "$NM"
    } > /etc/preamp/bootstrap.env
    chmod 0600 /etc/preamp/bootstrap.env

    Replace REPLACE_WITH_ORG_TOKEN with the token from step 1. To keep the token out of the Kandji script payload, you can instead read it from the enrollment profile: replace the TOK="REPLACE_WITH_ORG_TOKEN" line with TOK="$(/usr/bin/defaults read /Library/Managed\ Preferences/ai.preamp enrollmentToken 2>/dev/null || true)".

  5. Assign the Custom App to the same Blueprint as the two Custom Profiles, and scope it to the target devices.

  6. (Optional) Deploy a PPPC profile only if pre-granting Full Disk Access defensively. Use the template at installers/macos/pppc-template.xml in the agent repo, fill in $TEAM_ID and $CODE_REQUIREMENT, and upload via Library → Add new → Custom Profile. See the PPPC profile guide.

  7. (Optional) Tune runtime settings. Add schedule, allowUninstall, apiUrl, or other runtime knobs to the ai.preamp enrollment profile from step 2. See the managed preferences reference.

Verification

On a target Mac after the Blueprint applies:

  • The ai.preamp managed preference exists at /Library/Managed Preferences/ai.preamp.plist (required for the install to proceed).
  • /etc/preamp/bootstrap.env is absent (the postinstall deletes it on successful enroll; presence means enroll failed, check the Kandji activity log).
  • The agent does not appear in System Settings → Privacy & Security → Full Disk Access unless you deployed the optional PPPC profile. Its absence is expected.
  • The device shows up under the assigned user on app.preamp.ai/org/inventory/workforce. If it lands under Unattributed devices, the assigned user’s email domain isn’t in the org’s verified-domains list. Add it under app.preamp.ai → Settings → Domains and retry.

Failure modes

  • Console user is root at install time. Postinstall logs no console user; deferring enroll until next policy run and leaves the bootstrap file in place. The next Blueprint run picks it up.
  • Bootstrap env file is malformed (typo, missing =). Agent’s parser rejects malformed lines and preamp enroll exits non-zero, visible in the Kandji activity log. Bootstrap file stays in place for diagnosis.
  • Email outside verified domains. Enroll succeeds, device lands in the unattributed bucket. Verify domains and re-run.

Uninstall

Create a second Custom App for preamp-uninstaller-<version>.pkg, set to Install once, and scope it to the devices that should be removed. If allowUninstall: true is set in a managed-prefs Custom Profile, the uninstaller also cleans up per-user data trees.

Trust note

The org token in the pre-install script is sensitive. It appears in Kandji’s script payload and activity logs. Treat it like any other secret in your MDM tenant. Rotate via app.preamp.ai → Settings → Enrollment tokens → Revoke if exposed.