Skip to content

MDM Rollout

Every MDM rollout has the same three steps:

  1. Install the binary — push a signed artifact (.pkg / .msi / .deb / tarball) from the Quickstart download table.
  2. Drop the enrollment manifest — at the system path so every user on the machine inherits the binding. Generate the manifest on the Enrollment page.
  3. Verifytokenshift doctor reports back.

Paths used below:

  • macOS / Linux system manifest: /etc/tokenshift/enrollment.json
  • Windows system manifest: %PROGRAMDATA%\tokenshift\enrollment.json

See Enrollment for what’s in the manifest and why the per-user path takes precedence when both exist.

Two policies, scoped to the same smart group:

  1. Install — push the signed TokenShift .pkg (download it from the Quickstart download table and host it in your Jamf distribution point, or stream it via a wrapper script + curl).
  2. Configure — push the enrollment manifest as a file to /etc/tokenshift/enrollment.json (mode 0644, owned by root).

Run tokenshift doctor as a self-service “verify” policy so users (and your support team) can confirm the binding without admin help.

JumpCloud Commands work well for both steps:

  1. Push a shell command that downloads and installs the binary via curl | tar from the download URL.
  2. Push the manifest contents via a second Command that writes /etc/tokenshift/enrollment.json with tee.

Verify with a third Command that runs tokenshift doctor and captures output.

Windows-side: package the .msi and assign it to a device group. Manifest goes to %PROGRAMDATA%\tokenshift\enrollment.json — push it via an Intune Win32 app that drops the file in a post-install script, or via a separate configuration profile.

macOS-side: same as Jamf — .pkg install + manifest drop. Intune for Mac runs scripts as root, so writing /etc/tokenshift/enrollment.json is straightforward.

- name: download tokenshift
ansible.builtin.get_url:
url: "{{ tokenshift_download_url }}" # presigned URL from /install/quickstart/
dest: /tmp/tokenshift.tar.gz
mode: '0644'
- name: unpack and install
ansible.builtin.unarchive:
src: /tmp/tokenshift.tar.gz
dest: /usr/local/bin
remote_src: yes
creates: /usr/local/bin/tokenshift
- name: drop enrollment manifest
ansible.builtin.copy:
content: "{{ tokenshift_enrollment | to_nice_json }}"
dest: /etc/tokenshift/enrollment.json
owner: root
group: wheel
mode: '0644'
- name: verify
ansible.builtin.command: tokenshift doctor
register: doctor_out
changed_when: false

The manifest is read once at session start and cached for the lifetime of the process. Pushing a new manifest takes effect on the next agent session (or the next tokenshift invocation). No restart required for already-running shells beyond the agent itself.

Terminal window
# remove the binary
rm /usr/local/bin/tokenshift # macOS / Linux
# or msiexec /x … # Windows
# remove the system manifest
rm /etc/tokenshift/enrollment.json # macOS / Linux
del %PROGRAMDATA%\tokenshift\enrollment.json # Windows

tokenshift uninstall --purge removes hooks and per-user state but never touches the system-deployed manifest — that stays your MDM’s responsibility.