Kandji deployment
A complete Kandji rollout requires:
- An enrollment Custom Profile (preference domain
ai.preamp) carrying anenrollmentTokenkey. 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. - A Custom App with a pre-install script that writes
/etc/preamp/bootstrap.env, then installspreamp-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.plistexists with anenrollmentTokenkey, failing with a generic “contact the software manufacturer” error. Assign theai.preampCustom Profile (withenrollmentTokenset 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
fullnamein a separateai.preamp.identityCustom Profile and have the pre-install script read them viadefaults 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
-
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.
-
Create the enrollment Custom Profile. Library → Add new → Custom Profile with a preference domain
ai.preamppayload carryingenrollmentToken(value: the token from step 1) andmanaged=true. This satisfies the preinstall gate. Assign it to the Blueprint and confirm it installs before the Custom App runs. -
Create the identity Custom Profile. Add a second Custom Profile with preference domain
ai.preamp.identitycarryingemailandfullname, 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. -
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.envReplace
REPLACE_WITH_ORG_TOKENwith 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 theTOK="REPLACE_WITH_ORG_TOKEN"line withTOK="$(/usr/bin/defaults read /Library/Managed\ Preferences/ai.preamp enrollmentToken 2>/dev/null || true)". -
Assign the Custom App to the same Blueprint as the two Custom Profiles, and scope it to the target devices.
-
(Optional) Deploy a PPPC profile only if pre-granting Full Disk Access defensively. Use the template at
installers/macos/pppc-template.xmlin the agent repo, fill in$TEAM_IDand$CODE_REQUIREMENT, and upload via Library → Add new → Custom Profile. See the PPPC profile guide. -
(Optional) Tune runtime settings. Add
schedule,allowUninstall,apiUrl, or other runtime knobs to theai.preampenrollment profile from step 2. See the managed preferences reference.
Verification
On a target Mac after the Blueprint applies:
- The
ai.preampmanaged preference exists at/Library/Managed Preferences/ai.preamp.plist(required for the install to proceed). /etc/preamp/bootstrap.envis 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 underapp.preamp.ai → Settings → Domainsand retry.
Failure modes
- Console user is
rootat install time. Postinstall logsno console user; deferring enroll until next policy runand 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 andpreamp enrollexits 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.