Skip to main content

Kandji rollout

Roll out pavri-endpointd to a macOS fleet via Kandji using a custom-app Blueprint + audit-and-enforce script + signed .pkg.

1. Prerequisites

  • Pavri tenant + admin role.
  • Kandji admin access; permission to create Blueprints and Custom Apps.
  • Signed pavri-endpointd.pkg (Developer ID + Notarization). Signing is gated on CAP-3.8 — see the CAP-3.8 row in docs/05-PHASED-ROADMAP.md (internal).

2. Token mint

In the Pavri dashboard, navigate to Settings → Endpoints → Add Endpoint → Mint enrollment token. Tokens are single-use per endpoint, 24-hour TTL. Mint one token per Kandji Blueprint scope — re-use across endpoints within the blueprint is supported because the gateway tracks per-endpoint enrollment state.

3. Substitution markers

Edit infra/mdm/kandji/pavri-endpointd-blueprint.json before upload to Kandji:

MarkerReplace with
${GATEWAY_URL}Your tenant's gateway URL (e.g. https://gateway.your-org.pavri.ai)
${ENROLLMENT_TOKEN}The token you minted in step 2
${ORG_ID}Your pavri org_id (visible at /admin/tenant in the dashboard)

The environment block in the blueprint delivers these values directly to the LaunchDaemon via the audit-and-enforce script.

For the full list of supported environment variables and command-line flags, see Sensor deployment reference.

4. Package signing

Kandji delivers your .pkg. The package itself must be Developer-ID-signed and Apple-notarized (Apple's Gatekeeper enforces this on macOS 15+). Until CAP-3.8 ships the ES entitlement build, the sensor runs in observe-mode-only (Tier 2 kauth/FSEvents fallback). See macOS observer tiers.

5. Staged rollout

  1. Create a Kandji Blueprint pavri-pilot and assign it to a test device group (5% of fleet, using Kandji Assignment Maps or device tags).
  2. Upload the substituted pavri-endpointd-blueprint.json and the signed .pkg to the pavri-pilot Blueprint as a Custom App.
  3. Set the tenant default protection-profile to observe mode at /admin/protection-profiles.
  4. After 1 week of clean telemetry: expand the Blueprint assignment to 25% of fleet, switch tenant default to soft_enforce.
  5. After 1 further week: expand to 100% and switch to enforce.

The audit-and-enforce.sh script runs on Kandji's enforcement schedule (default: every 4 hours). If the sensor is found absent or unhealthy, Kandji re-installs automatically.

6. Rollback

  • Per-endpoint emergency: at /admin/endpoints/{endpoint_id} → Set protection mode → observe — takes effect immediately, no Kandji touch required.
  • Fleet-wide emergency: at /admin/protection-profiles → set tenant default to observe.
  • Full uninstall via Kandji: remove the Custom App from the Blueprint assignment. Kandji will not automatically uninstall custom apps; use a separate self-service or remote command to run /usr/local/bin/endpointctl uninstall-nm-manifests --browser=all and pkgutil --forget com.pavri.endpointd.

7. Post-install verification

On any enrolled endpoint:

# Verify the binary is present.
ls -l /usr/local/bin/pavri-endpointd

# Verify the LaunchDaemon is loaded and running.
sudo launchctl print system/com.pavri.endpointd | grep -E 'state|pid'

# Verify native-messaging manifests are healthy for any browsers in scope.
/usr/local/bin/endpointctl status-nm-manifests --browser=all

Confirm the endpoint shows up at /admin/endpoints in the dashboard within 60 seconds of the heartbeat interval. The Kandji audit script exit code (0 = compliant) is also visible in the Kandji Device Details pane under Custom Apps.

Files in this rollout

  • infra/mdm/kandji/pavri-endpointd-blueprint.json — Kandji custom-app blueprint.
  • infra/mdm/kandji/blueprint.schema.json — JSON Schema for CI validation.
  • infra/mdm/kandji/audit-and-enforce.sh — Kandji enforcement script.
  • infra/mdm/kandji/README.md — short on-disk reference for Kandji operators.