MDM Deployment
Deploy IDEViewer silently to managed macOS devices via JAMF, Mosyle, Kandji, or other MDM solutions.
What Gets Deployed
| Component | Path | Purpose |
|---|---|---|
| Binary | /usr/local/bin/ideviewer | CLI + daemon |
| Uninstaller | /usr/local/bin/ideviewer-uninstall | Clean removal |
| LaunchAgent | /Library/LaunchAgents/com.ideviewer.daemon.plist | Auto-start as user |
| Logs | /tmp/ideviewer-daemon.log | Daemon output |
| Config | ~/.ideviewer/config.json | Portal connection (created on register) |
Deployment Steps
1. Build or Download the .pkg
# Build from source
./build_scripts/build_all.sh --macos
# Or download from GitHub Releases
# https://github.com/securient/ideviewer-oss/releases
2. Upload PPPC Profile
The PPPC (Privacy Preferences Policy Control) profile grants the daemon Full Disk Access so it can scan IDE extensions, project directories, and config files without prompting the user.
Deploy the PPPC profile before the .pkg installer. If the profile arrives after the binary is already running, users may see permission prompts.
File: deploy/mdm/ideviewer-tcc.mobileconfig
JAMF Pro
- Go to Computers > Configuration Profiles
- Click New
- Under Privacy Preferences Policy Control, click Upload
- Upload
ideviewer-tcc.mobileconfig - Scope to target devices/groups
- Save
Mosyle
- Go to Management > Profiles
- Click Add Profile > Custom
- Upload
ideviewer-tcc.mobileconfig - Assign to devices
Kandji
- Go to Library > Custom Profile
- Upload
ideviewer-tcc.mobileconfig - Assign to blueprint
Manual Testing
sudo profiles install -path deploy/mdm/ideviewer-tcc.mobileconfig
3. Deploy the .pkg Installer
JAMF Pro
- Go to Computer Management > Packages
- Upload
IDEViewer-0.3.0.pkg - Create a Policy:
- Trigger: Enrollment Complete + Recurring Check-in
- Packages: Install
IDEViewer-0.3.0.pkg - Scope: Target devices
- The postinstall script handles directory creation and permissions
Mosyle / Kandji / Other
Upload the .pkg as a managed installer and deploy to target devices.
4. Register with Portal
After the .pkg is installed, the daemon needs to register with your portal. Create a JAMF script or MDM command:
#!/bin/bash
# Run as the logged-in user (not root) so config goes to user's home
LOGGED_IN_USER=$(stat -f%Su /dev/console)
CUSTOMER_KEY="YOUR-CUSTOMER-KEY-HERE"
PORTAL_URL="https://portal.yourcompany.com"
sudo -u "$LOGGED_IN_USER" /usr/local/bin/ideviewer register \
--customer-key "$CUSTOMER_KEY" \
--portal-url "$PORTAL_URL"
JAMF Pro:
- Go to Computer Management > Scripts
- Create a new script with the above content
- Set Priority: After
- Add to the same Policy as the .pkg install
- Set to run as Current User (not root)
5. Verify Deployment
Check enrollment from the portal or run on a target machine:
ideviewer version
launchctl list | grep ideviewer
tail -f /tmp/ideviewer-daemon.log
Silent Upgrade
- Build or download the new .pkg
- Upload to JAMF as a new package version
- Create an upgrade policy (the preinstall script stops the old daemon)
- The LaunchAgent restarts automatically (
KeepAlive=true)
Silent Uninstall
#!/bin/bash
sudo /usr/local/bin/ideviewer-uninstall <<< "y"
Or deploy as a JAMF script for non-interactive removal.
Code Signing
For production MDM deployments, code sign the binary and update the PPPC profile:
# Sign the binary
codesign --sign "Developer ID Application: Your Company (TEAMID)" \
--options runtime \
dist/ideviewer-darwin-arm64
# Get the code requirement
codesign -dr - dist/ideviewer-darwin-arm64
Then update ideviewer-tcc.mobileconfig:
- Change
IdentifierTypefrompathtobundleID - Set
Identifiertocom.ideviewer.daemon - Add
CodeRequirementwith the output fromcodesign -dr
Troubleshooting
| Issue | Solution |
|---|---|
| TCC prompt still appears | Ensure PPPC profile is deployed BEFORE the .pkg |
| Daemon not scanning | Check launchctl list \| grep ideviewer – exit code 0 means running |
| No data in portal | Verify registration: cat ~/.ideviewer/config.json |
| Wrong user context | LaunchAgent runs as logged-in user; do not use LaunchDaemon |
| Daemon stops on logout | Expected for LaunchAgent – restarts on next login |