> ## Documentation Index
> Fetch the complete documentation index at: https://silmaril.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Iru

> Deploy Silmaril with a System Channel profile and an audit-and-enforce Custom App.

export const macosRelease = {
  "version": "0.3.22",
  "build": "1077",
  "guardianEnabled": false,
  "minimumOS": "macOS 14 or later",
  "dmgUrl": "https://downloads.silmaril.dev/macos/releases/0.3.22/1077/Silmaril-0.3.22-1077-guardian-disabled.dmg",
  "pkgUrl": "https://downloads.silmaril.dev/macos/releases/0.3.22/1077/Silmaril-0.3.22-1077-guardian-disabled.pkg",
  "mdmZipUrl": "https://downloads.silmaril.dev/macos/releases/0.3.22/1077/Silmaril-0.3.22-1077-guardian-disabled-MDM.zip",
  "mdmChecksumUrl": "https://downloads.silmaril.dev/macos/releases/0.3.22/1077/Silmaril-0.3.22-1077-guardian-disabled-MDM.zip.sha256",
  "mdmSHA256": "86efaf60414339c97c5fcaac86d98b215f44010798f58e83ea3850b1243fd92a"
};

<a id="iru" />

<a id="kandji" />

<a id="iru-guardian-disabled" />

<a id="iru-profile-changes-title" />

Deploy Stable {macosRelease.version} (build {macosRelease.build}) with a System Channel Custom Profile and an audit-and-enforce Mac Custom App. Iru was formerly Kandji.

## Deploy with Iru

<Steps>
  <Step title="Prepare">
    Have administrator access, an enrolled Mac running {macosRelease.minimumOS}, and the vendor management agent where required. Download the Stable {macosRelease.version} ({macosRelease.build}) Guardian Disabled PKG and complete the required configuration before upload.

    **Expected result**<br />
    The completed `Silmaril-Managed.mobileconfig` has passed validation, and the package is the <a href={macosRelease.pkgUrl}>Stable PKG</a>.

    **If this differs**<br />
    Finish the [rollout plan](/docs/macos/managed-deployment) before creating the Library Items.
  </Step>

  <Step title="Upload the System Channel profile">
    Create an Iru Custom Profile Library Item, upload the completed `Silmaril-Managed.mobileconfig`, and use System Channel.

    Keep the Mac on its existing base Blueprint. On that Blueprint's Assignment Map, add a conditional node for a dedicated tag such as `silmaril`. Place this profile behind that condition, and leave baseline Library Items outside it.

    Do not move the Mac to a separate Silmaril Blueprint. Changing Blueprints can remove baseline profiles. The condition matches a Mac that contains one of the listed tags, so other tags on the Mac can remain.

    If the same profile identity already exists, update that Library Item instead of creating a duplicate.

    **Expected result**<br />
    One Custom Profile Library Item holds this profile identity, on System Channel, behind the `silmaril` condition on the existing base Blueprint. Baseline items stay outside that condition.

    **If this differs**<br />
    Update the existing Library Item when `dev.silmaril.mdm.managed` is already present. A second profile with the same identity is outside this workflow. Moving the Mac to another Blueprint is also outside this workflow.
  </Step>

  <Step title="Wait for profile completion">
    Use the Library Item Status tab and target device Activity to confirm the InstallProfile operation completed before assigning the app. The shared conditional node does not order the profile and the app.

    For the initial pilot, leave the Mac Custom App unassigned until Activity shows that operation completed. Profile delivery can take time.

    Before you apply the `silmaril` tag to any later Mac, use the [later-cohort hold](#iru-later-cohort).

    **Expected result**<br />
    That profile's InstallProfile operation has completed on the initial pilot Mac.

    **If this differs**<br />
    For the initial pilot, leave the Mac Custom App unassigned until Activity shows that operation completed. Assigning the app earlier skips the required order.
  </Step>

  <Step title="Create the Mac Custom App">
    Create a Mac Custom App with Package Type Installer Package, upload the {macosRelease.version} ({macosRelease.build}) PKG, choose Audit and enforce, leave restart disabled, and use the Guardian Disabled audit and console-user post-install scripts below. Exit 0 means a matching Guardian Disabled build at or above minimum build {macosRelease.build} is installed. A nonzero audit result triggers enforcement. The minimum-build check accepts {macosRelease.build} or newer and prevents downgrade. Assign it to the same Assignment Map condition as the profile, and only after that profile install is confirmed on those Macs.

    **Expected result**<br />
    Audit exits 0 for bundle ID `dev.silmaril.SilmarilMacOS`, Guardian Disabled, and build {macosRelease.build} or newer. The post-install script opens Silmaril for a signed-in console user above UID 500. With no signed-in user, it exits 0 and the profile opens Silmaril at the next login.

    **If this differs**<br />
    A nonzero audit means that match is not installed, so Iru enforcement runs. Restart stays disabled. An audit that passes and a package that installs still leave protection unconfirmed until [verification](/docs/macos/verify).
  </Step>

  <Step title="Hold each later cohort">
    <a id="iru-later-cohort" />

    After the Custom App is on the `silmaril` condition, a newly tagged Mac receives the profile and the app together. For every later cohort, hold the app before you apply the tag.

    Edit the Assignment Map and select the Silmaril Mac Custom App. Expand Manual device exclusions, choose Add device, select each new Mac, and Save. Leave the profile and the baseline items assigned. Saving the map reevaluates the rules. On the map or in device lookup, confirm the app is excluded. Device lookup highlights the Library Items assigned to that Mac.

    Then add the `silmaril` tag to that cohort. Confirm InstallProfile has completed on each of those Macs. Only then remove just those Macs from the Custom App exclusions with the X control and Save. That permits the app. Do not use Clear all, and do not change exclusions for other devices.

    Keep the same tag condition on the existing base Blueprint. Do not create another Blueprint or a second tag. An exclusion holds app deployment. It is not an uninstall.

    **Expected result**<br />
    Each new Mac stays excluded from the Silmaril Custom App while its profile installs, and baseline items stay in place. After InstallProfile completes, removing that Mac from the exclusion permits the app.

    **If this differs**<br />
    Do not apply the `silmaril` tag until the exclusion is saved and lookup shows the app excluded. Do not remove an exclusion while InstallProfile is still incomplete for that Mac.
  </Step>

  <Step title="Verify">
    Open Silmaril on a pilot Mac and complete [endpoint verification](/docs/macos/verify). The profile supplies the connection values. Package success or a Managed label alone does not confirm protection.

    **Expected result**<br />
    Endpoint verification shows the app identity, a Managed connection, and fresh Protection activity from a new agent session.

    **If this differs**<br />
    Keep the rollout on the pilot. Use [troubleshooting](/docs/macos/troubleshooting). Restart required means fully quit and reopen the affected agent, then start a new session.
  </Step>

  <Step title="Update or replace policy">
    For an update, deploy only the intended Guardian Disabled version and update supported app/package metadata at the same time. Replace the existing profile while preserving all supplied profile and payload identifiers, UUIDs, and permissions. Never invent identifiers to bypass a conflict. Removing managed keys restores saved local preferences. Removing the profile does not uninstall Silmaril.

    **Expected result**<br />
    The same profile identity remains, the app metadata matches the intended Guardian Disabled build, and a pilot Mac passes [verification](/docs/macos/verify).

    **If this differs**<br />
    Restore the supplied profile identity and confirm the installed build before expanding the rollout. Add later Macs through the [later-cohort hold](#iru-later-cohort) before applying the `silmaril` tag. Removing the profile leaves the app installed.
  </Step>

  <Step title="Uninstall">
    Pause every Silmaril Mac Custom App assignment for the target Macs so Iru cannot reinstall Silmaril. Leave the base Blueprint and its baseline Library Items in place.

    Removing the `silmaril` tag does not uninstall Silmaril.

    Run the shared [Uninstall through MDM](/docs/macos/uninstall) script as root with the affected user signed in, and retain the JSON receipt and exit code. Exit 2 reports remaining items to review. It does not identify Guardian residue.

    Follow the shared result-handling instructions and remove only the Silmaril profile when policy should no longer apply. Leave baseline assignments and controls in place. Do not delete the Blueprint.

    Paste the script into the Audit Script field of an Iru Custom Script Library Item, leave Restart disabled, and do not add a remediation script. Inspect its script output and exit code. Install once per device retries nonzero results. If the exit 2 receipt confirms app removal and Guardian absence with only permissions remaining, unassign the removal item and complete the reported permission follow-up instead of rerunning the missing helper.

    **If this differs**<br />
    An exit 2 receipt that shows the app and Guardian gone, with only permissions left, is finished by unassigning the removal item and completing the permission follow-up. Rerunning after the helper is gone cannot turn that result into exit 0.
  </Step>
</Steps>

## Guardian Disabled audit script

Exit 0 means bundle ID `dev.silmaril.SilmarilMacOS`, Guardian Disabled (`SilmarilPrivilegedProtectionEnabled` false), and `CFBundleVersion` greater than or equal to `MIN_BUILD`. `MIN_BUILD` is the numeric Stable build {macosRelease.build}. Any other result exits 1.

```bash theme={"theme":"github-light-default"}
#!/bin/bash

APP="/Applications/Silmaril.app"
BIN="$APP/Contents/MacOS/Silmaril"
PLIST="$APP/Contents/Info.plist"
EXPECTED_BUNDLE_ID="dev.silmaril.SilmarilMacOS"
MIN_BUILD="1077"
EXPECTED_GUARDIAN_ENABLED="0"

case "$MIN_BUILD" in
  ''|*[!0-9]*) exit 1 ;;
esac

if [[ ! -x "$BIN" || ! -f "$PLIST" ]]; then
  exit 1
fi

bundle_id="$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$PLIST" 2>/dev/null)" || exit 1
installed="$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$PLIST" 2>/dev/null)" || exit 1
guardian="$(/usr/libexec/PlistBuddy -c "Print :SilmarilPrivilegedProtectionEnabled" "$PLIST" 2>/dev/null)" || exit 1

case "$installed" in
  ''|*[!0-9]*) exit 1 ;;
esac

case "$guardian" in
  true) guardian_enabled=1 ;;
  false) guardian_enabled=0 ;;
  *) exit 1 ;;
esac

if [[ "$bundle_id" == "$EXPECTED_BUNDLE_ID" ]] &&
   [[ "$guardian_enabled" == "$EXPECTED_GUARDIAN_ENABLED" ]] &&
   (( 10#$installed >= 10#$MIN_BUILD )); then
  exit 0
fi

exit 1
```

## Console-user post-install script

With no signed-in user, the script exits 0 and the profile opens Silmaril at the next login.

```bash theme={"theme":"github-light-default"}
#!/bin/bash

APP="/Applications/Silmaril.app"
[[ -x "$APP/Contents/MacOS/Silmaril" ]] || exit 1

console_uid="$(/usr/bin/stat -f %u /dev/console)" || exit 1
case "$console_uid" in
  ''|*[!0-9]*) exit 1 ;;
esac

# With no signed-in user, the profile opens Silmaril at the next login.
[[ "$console_uid" -gt 500 ]] || exit 0

/bin/launchctl asuser "$console_uid" \
  /usr/bin/sudo -n -H -u "#$console_uid" \
  /usr/bin/open "$APP"
```

## Vendor references

* [Custom Profiles overview](https://docs.iru.com/en/endpoint/library/library-items-profiles/custom-profiles-overview)
* [Configure a Mac Custom App](https://docs.iru.com/en/endpoint/library/library-items-profiles/configure-the-custom-apps-library-item)
* [Library Item status and activity](https://docs.iru.com/en/endpoint/library/library-items-profiles/library-item-status-activity-timeline)
* [Custom Scripts overview](https://docs.iru.com/en/endpoint/library/library-items-profiles/custom-scripts-overview)
* [Conditional logic in Assignment Maps](https://support.kandji.io/kb/using-conditional-logic-in-assignment-maps)
* [Move a device to a different Blueprint](https://support.kandji.io/kb/move-a-device-to-a-different-blueprint)
