Intune deployment
macOS uses the universal signed PKG. Windows uses the promoted IntuneWin from the production feed. A signed workflow candidate remains validation-only until the release evidence gates pass and a...
Universal macOS PKG · Signed Windows IntuneWin
macOS uses the universal signed PKG. Windows uses the promoted IntuneWin from the production feed. A signed workflow candidate remains validation-only until the release evidence gates pass and a reviewed feed update points to the same package hashes.
macOS
Current package versions and checksums are published with the release artifacts. See Download artifacts.
Before deployment, subscribe to installer updates.
Create the profile
Create a macOS Enterprise Installer token with Microsoft Intune selected. The deployment ID in the profile must match the token.
The token is reusable for Macs in this scoped deployment until it expires or is revoked. Keep it only in the restricted Intune app script. Rotate it immediately after exposure and revoke it when the deployment ends.
Save the following as AgentKeeper.mobileconfig. Replace the organization and
deployment values:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>PayloadType</key>
<string>com.apple.ManagedClient.preferences</string>
<key>PayloadIdentifier</key>
<string>com.agentkeeper.runtime.preferences.intune</string>
<key>PayloadUUID</key>
<string>561A15C9-3A42-4821-A56F-71EBA5FA0F60</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadEnabled</key>
<true/>
<key>PayloadContent</key>
<dict>
<key>com.agentkeeper.runtime</key>
<dict>
<key>Forced</key>
<array>
<dict>
<key>mcx_preference_settings</key>
<dict>
<key>api_url</key>
<string>https://agentkeeper.dev</string>
<key>org_id</key>
<string>YOUR_AGENTKEEPER_ORG_ID</string>
<key>mdm_provider</key>
<string>intune</string>
<key>mdm_deployment_id</key>
<string>YOUR_AGENTKEEPER_DEPLOYMENT_ID</string>
</dict>
</dict>
</array>
</dict>
</dict>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>AgentKeeper Runtime</string>
<key>PayloadIdentifier</key>
<string>com.agentkeeper.runtime.intune</string>
<key>PayloadOrganization</key>
<string>AgentKeeper</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>9DAD3BCB-0FF0-46E5-BBDE-EAB2C5A1383A</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>
In Intune, create a macOS Custom configuration profile, upload the file,
and select Device channel. Assign it to the same macOS device group as the
PKG. Do not use User channel: the LaunchDaemon reads the computer-level profile
from /Library/Managed Preferences/com.agentkeeper.runtime.plist. Do not add a
UPN, local account name, or dynamic user variable. User affinity is not required
for AgentKeeper enrollment.
Before assigning the PKG, verify the installed value:
#!/bin/bash
set -euo pipefail
PROFILE="/Library/Managed Preferences/com.agentkeeper.runtime.plist"
if [[ ! -f "$PROFILE" || -L "$PROFILE" ]]; then
echo "AgentKeeper profile is missing or invalid" >&2
exit 1
fi
for key in api_url org_id mdm_provider mdm_deployment_id; do
sudo /usr/bin/plutil -extract "$key" raw -o - "$PROFILE" 2>/dev/null \
| /usr/bin/grep -q '[^[:space:]]' || exit 1
done
if [[ "$(sudo /usr/bin/plutil -extract mdm_provider raw -o - "$PROFILE")" != "intune" ]]; then
echo "AgentKeeper profile has the wrong MDM provider" >&2
exit 1
fi
if sudo /usr/bin/plutil -extract enrollment_token raw -o - "$PROFILE" >/dev/null 2>&1; then
echo "Remove enrollment_token from the AgentKeeper profile" >&2
exit 1
fi
echo "AgentKeeper device profile ready"
Never add enrollment_token to the profile. The runtime checks for profile
changes each minute, but profile-first assignment keeps deployment results
deterministic.
Add the PKG app
- Verify the PKG against
checksums.txt, its Developer ID Installer signature, stapler, and Gatekeeper. - In the Intune admin center, go to Apps > All apps > Create.
- Choose macOS app (PKG) and upload the package using the unmanaged PKG app type.
- Remove any incorrectly inferred entries from Included apps. Do not invent an
.appbundle ID; AgentKeeper installs a LaunchDaemon and command line runtime. - In Program, add this Post-install script, replacing the token
placeholder. The script runs after the PKG and stages the token through
standard input. Intune requires Microsoft Intune management agent version
2309.007or later for PKG pre- and post-install scripts:
#!/bin/bash
set -euo pipefail
set +x
AGENTKEEPER_ENROLLMENT_TOKEN='PASTE_ENTERPRISE_INSTALLER_TOKEN'
trap 'unset AGENTKEEPER_ENROLLMENT_TOKEN' EXIT
BIN="/Library/Application Support/AgentKeeper/bin/agentkeeper"
REMEDIATE="/Library/Application Support/AgentKeeper/helpers/agentkeeper-macos-remediate.sh"
if [[ "$(id -u)" -ne 0 || ! -x "$BIN" || ! -x "$REMEDIATE" ]]; then
echo "AgentKeeper PKG is not ready for enrollment" >&2
exit 1
fi
printf '%s' "$AGENTKEEPER_ENROLLMENT_TOKEN" | "$BIN" \
stage-managed-enrollment \
--token-stdin \
--program-data "/Library/Application Support/AgentKeeper" \
--install-dir "/Library/Application Support/AgentKeeper"
unset AGENTKEEPER_ENROLLMENT_TOKEN
"$REMEDIATE"
- Assign the app as Required to the target macOS device group.
The package installs the runtime. The Post-install script stages a root-only
0600 token and starts enrollment and reconciliation. A Platform Script may
report package, LaunchDaemon, and status-helper state, but it must not become a
second installer.
Machine enrollment can complete before anyone signs in. After a regular
non-root user signs in, the runtime resolves the active console account through
macOS Directory Services and reconciles that account automatically. It repeats
this after a user switch and never scans /Users.
Verify
pkgutil --pkg-info dev.agentkeeper.runtime
sudo launchctl print system/com.agentkeeper.runtime
sudo "/Library/Application Support/AgentKeeper/helpers/agentkeeper-macos-status.sh"
Status must show enrollment_state="enrolled",
managed_profile_state="ready", hook_matrix.config_json=true, and
credential_state="valid". Then restart one selected AI agent and confirm a
fresh live Activity event.
Before sign-in, status can show targeting_mode="active_console_user", no
active_console_user, and maintenance_state="waiting_for_user" while the
machine is already enrolled. After sign-in or a user switch, wait for the
one-minute maintenance tick or run the installed remediation helper; do not add
a username to the profile.
Intune reports the PKG app as installed even when its Post-install script fails.
Use the status command above, not the app installation result, to confirm
enrollment. enrollment_state="managed_token_missing" means the metadata
profile arrived but the token-staging script did not complete.
The Intune unmanaged PKG app type has no Uninstall assignment. Run the installed AgentKeeper uninstall helper before retiring a Mac. See Uninstall and rollback.
Microsoft documents the app type in Add an unmanaged macOS PKG app.
Windows
Windows uses agentkeeper-runtime-windows-latest.intunewin and its
package-matched PowerShell helpers. Follow Windows enterprise
install for the current download, install,
detection, and uninstall commands. The macOS PKG and Post-install script on
this page do not apply to Windows.
- Download
agentkeeper-runtime-windows-latest.intunewinand its matchingagentkeeper-runtime-intunewin-source.zip. - Create a Windows app (Win32) in Intune.
- Enter the app information and Program fields manually. An
.intunewinis a content container and does not populate install commands, detection rules, requirements, or assignments. - Set Install behavior to System, Device restart behavior to No specific action, and select both x64 and ARM64 under Requirements.
- Use the package-matched install and uninstall commands through
%SystemRoot%\Sysnative\WindowsPowerShell\v1.0\powershell.exe. - Under Detection rules, choose Use a custom detection script and
upload
detect.ps1extracted from that exact source ZIP. Set Run script as 32-bit process on 64-bit clients to No. - Assign the app as Required to the intended Windows device group.
Available for enrolled devices does not install the app automatically; it waits for the user to select Install in Company Portal. Use the complete Windows enterprise install walkthrough for test-device enrollment, Enterprise Installer token creation, every portal field, device-group assignment, manual sync, status interpretation, upgrade, and log collection.
AgentKeeper supports Microsoft Entra automatic enrollment and Windows Autopilot. Neither is required for a small test: a licensed user can enroll an existing Windows device through Company Portal without Microsoft Entra ID P1 or P2, provided the Windows account doing the enrollment is a local administrator.
Do not configure detection as a PowerShell command. The uploaded detector
contains the package's immutable exact version. Every package upgrade must
replace both the .intunewin and the uploaded detect.ps1; reusing the prior
detector intentionally makes the upgraded app report as not installed.
Create the token in Settings > Access > API keys > Enterprise Installer
tokens. Choose Windows / Intune, and make the token deployment ID and
surface scope match the install command. The -MdmDeploymentId value must be
the exact Deployment ID shown under the token's Deployment scope, not
the token's display Name. Do not use a fleet API key, Microsoft Graph
secret, or manually assigned machine ID.
Run the helpers with Windows PowerShell 5.1 through
%SystemRoot%\Sysnative.
The package installs one canonical all-IDE hook at
C:\ProgramData\AgentKeeper\agentkeeper-ide-hook.ps1. Cursor, Windsurf,
Copilot CLI, Gemini CLI, and Codex use machine-managed configuration under
C:\ProgramData; Copilot's policy file is
C:\ProgramData\GitHub\Copilot\policy.d\agentkeeper.json. Antigravity stores
its hook configuration in the resolved developer profile, but that configuration
points to the same canonical hook under C:\ProgramData. Claude Code uses the
runtime's dedicated Claude and SessionStart forwarders from the machine-managed
base file at C:\Program Files\ClaudeCode\managed-settings.json.
Claude Code's configuration reference
documents Windows file-based managed settings under C:\Program Files\ClaudeCode.
AgentKeeper does not use the retired C:\ProgramData\ClaudeCode location or
managed-settings.d for its Windows hooks. A developer's
%USERPROFILE%\.claude\settings.json is considered only for safe cleanup of
legacy AgentKeeper entries after the managed repair succeeds.
The default IdeTargets=all selection requires exactly one strong Windows
account, SID, and mounted profile because it includes Antigravity. Set
TargetUser or TargetUserUpn when Intune cannot identify exactly one active
developer session. AgentKeeper persists that target so Antigravity repair,
detection, status, and uninstall do not guess again. Any selection that omits
Antigravity is machine-scoped, including Claude Code, and does not require an
interactive target user. For mixed all, Builtin Users receives the narrow
runtime-asset access needed by machine-scoped hooks while the resolved SID is
used for Antigravity's profile config.
Repair preserves unrelated customer hooks. If a selected JSON or TOML config is malformed, AgentKeeper leaves it unchanged and reports a nonzero repair/detection result. Any selected hook repair failure fails the unified install instead of reporting a partial installation as healthy.
Inventory sync
Intune inventory sync is optional identity enrichment. Microsoft Graph credentials stay in the server-side AgentKeeper MDM connection and never belong in endpoint configuration.