Deployment
Deploying Talon
Per-platform, exhaustively — this is where trials die.
Every path below includes silent-install flags, a verification command, uninstall, and log locations. If a path you need is missing, that is a documentation bug and we want to hear about it.
Windows
MSI with a transform
msiexec /i talon-1.8.2-x64.msi TRANSFORMS=site.mst ^ ENROLL_TOKEN=<token> DEVICE_GROUP="Standard Laptops" ^ /qn /norestart /l*v C:\Windows\Temp\talon-install.log
| Property | Purpose | Required |
|---|---|---|
| ENROLL_TOKEN | Single-use enrollment token from Manning | Yes |
| DEVICE_GROUP | Initial Cadge group. Determines which Creance policy applies. | No |
| TENANT | Only needed for multi-tenant MSP deployments | No |
| PROXY | Explicit egress proxy, e.g. http://proxy:3128 | No |
Intune / Autopilot
- 01Wrap the MSI with IntuneWinAppUtil. Install command as above; uninstall command msiexec /x {PRODUCT-GUID} /qn.
- 02Detection rule: file %ProgramFiles%\\Kestrel\\talon.exe, version greater than or equal to 1.8.2.
- 03Assign to a device group, not a user group. Talon is a machine-scoped service.
- 04Set Device restart behaviour to No specific action. Talon never requires a reboot to install.
GPO
Computer Configuration → Policies → Software Settings → Software Installation. Assign, do not publish. Place the MSI on a UNC path readable by Domain Computers, and pass the token via a transform rather than a startup script — a token in a script is a token in SYSVOL.
RMM script deployment
$token = "<token>"
$url = "https://dl.kestrel.io/talon/1.8.2/talon-1.8.2-x64.msi"
$msi = "$env:TEMP\talon.msi"
Invoke-WebRequest -Uri $url -OutFile $msi -UseBasicParsing
# Verify the Authenticode signature before installing. Do this even though
# you trust the URL — especially in an RMM, where the script is the
# highest-value target on the machine.
$sig = Get-AuthenticodeSignature $msi
if ($sig.Status -ne 'Valid' -or
$sig.SignerCertificate.Subject -notlike '*Kestrel Systems*') {
throw "Signature check failed: $($sig.Status)"
}
Start-Process msiexec -ArgumentList @(
"/i", "`"$msi`"", "ENROLL_TOKEN=$token", "/qn", "/norestart"
) -Wait -NoNewWindow
& "$env:ProgramFiles\Kestrel\talon.exe" statuswinget
winget install Kestrel.Talon --silent \ --override "ENROLL_TOKEN=<token> /qn"
Verify, uninstall, logs
# verify
& "$env:ProgramFiles\Kestrel\talon.exe" status
Get-Service TalonAgent
# uninstall
msiexec /x {A7F2C104-9E31-4B8D-95CE-0D2B7A1F6E44} /qn
# logs
%ProgramData%\Kestrel\logs\talon.log
%ProgramData%\Kestrel\logs\actions\macOS
The PKG is signed with a Developer ID and notarised. Verify before deploying at scale:
spctl -a -vvv -t install Talon-1.8.2.pkg pkgutil --check-signature Talon-1.8.2.pkg
The PPPC profile
Copy-paste this payload into Jamf (Configuration Profiles → Privacy Preferences Policy Control), Kandji or Mosyle. The designated requirement is fixed; do not retype it.
<key>Services</key>
<dict>
<key>SystemPolicyAllFiles</key>
<array>
<dict>
<key>Identifier</key>
<string>io.kestrel.talon</string>
<key>IdentifierType</key>
<string>bundleID</string>
<key>CodeRequirement</key>
<string>identifier "io.kestrel.talon" and anchor apple generic
and certificate leaf[subject.OU] = "K3STR3LSYS"</string>
<key>Authorization</key>
<string>Allow</string>
</dict>
</array>
</dict>Talon requires SystemPolicyAllFiles to read diagnostic metadata across the filesystem. It does not request ScreenCapture, Camera, Microphone, Accessibility or ListenEvent, and the notarised bundle contains no such entitlement — which you can verify yourself with codesign -d --entitlements.
Jamf, Kandji, Mosyle
- 01Upload the PPPC profile and scope it to the target smart group. Confirm it lands before proceeding.
- 02Upload the signed PKG as a package.
- 03Create a policy with a script payload that writes the enrollment token to /var/tmp/kestrel-enroll and then installs.
- 04Scope to the same smart group. Set the trigger to enrollment complete plus recurring check-in.
# verify /usr/local/bin/talon status launchctl print system/io.kestrel.talon # uninstall sudo /usr/local/bin/talon uninstall --purge # logs /Library/Logs/Kestrel/talon.log log show --predicate 'subsystem == "io.kestrel.talon"' --last 1h
Linux
curl -fsSL https://dl.kestrel.io/apt/kestrel.gpg \ | sudo tee /usr/share/keyrings/kestrel.gpg > /dev/null echo "deb [signed-by=/usr/share/keyrings/kestrel.gpg] \ https://dl.kestrel.io/apt stable main" \ | sudo tee /etc/apt/sources.list.d/kestrel.list sudo apt update && sudo apt install talon sudo talon enroll --token <token> --group "Servers"
sudo rpm --import https://dl.kestrel.io/yum/kestrel.asc sudo tee /etc/yum.repos.d/kestrel.repo <<'EOF' [kestrel] name=Kestrel baseurl=https://dl.kestrel.io/yum/stable gpgcheck=1 gpgkey=https://dl.kestrel.io/yum/kestrel.asc EOF sudo dnf install talon sudo talon enroll --token <token>
- hosts: endpoints
become: true
roles:
- role: kestrel.talon
vars:
talon_enroll_token: "{{ vault_kestrel_token }}"
talon_device_group: "Servers"
talon_version: "1.8.2"# verify systemctl status talon talon status # uninstall sudo apt remove --purge talon # or: sudo dnf remove talon # logs journalctl -u talon -f /var/log/kestrel/talon.log
Network egress
Talon makes outbound connections only. It opens no listening port on any platform.
| Destination | Port | Purpose |
|---|---|---|
| ingest.kestrel.io | 443 (gRPC/mTLS) | Telemetry, action dispatch, results |
| standdown.kestrel.io | 443 | Recall — deliberately separate infrastructure from ingest |
| dl.kestrel.io | 443 | Agent and Quarry bundle downloads |
| ocsp.kestrel.io | 80 | Certificate revocation checking |