Skip to main content
KBY Technologies Logo
The Ops Playbook

Auto-Remediating FileVault Recovery Key Escrow Failures

Detect and auto-remediate missing FileVault recovery key escrow on managed Macs using Jamf Pro or Intune before it becomes a lockout ticket.

Auto-Remediating FileVault Recovery Key Escrow Failures
Isla Morgan 18 July 202610 min read Tier L2 35 min setupDevice Management

Operational brief

Operational outcome

Detect and auto-remediate missing FileVault recovery key escrow on managed Macs using Jamf Pro or Intune before it becomes a lockout ticket.

Target Tier

L2 support

Implement within an approved test scope before wider deployment.

Time to set aside

About 35 minutes

Includes configuration, validation and deployment.

Share
Tutorial navigation
Innovation note
Verify your deployment with small rollout groups and enforce least-privilege administrative access when implementing these automations.

#The Old Way vs the New Way

The old way looks like this: a user forgets their Mac password on a Monday morning, the MDM console shows a recovery key on file, the technician retrieves it, types it in over a screen-share, and it fails. The key on file was generated before the last password change, or the FileVault Recovery Key Redirection profile silently failed to escrow after a macOS upgrade, or the Mac enrolled before the profile was ever scoped to it. The technician now has an angry user, a locked drive, and no working key. The only remaining option is a full data wipe and re-image, which turns a five-minute unlock into a half-day incident.

The new way treats recovery key escrow as a fleet health signal, not a support ticket. Managed Macs report their escrow status back to inventory on a schedule. Any Mac where the individual recovery key is missing, invalid, or unverified is automatically flagged, silently remediated by forcing a key rotation and re-escrow, and re-verified against the MDM server before the user ever notices. Technicians only get paged when automated remediation fails twice in a row, which is the genuine escalation-worthy event.

#Prerequisites and Permissions

  • Jamf Pro 10.x or later, or Microsoft Intune with the macOS platform enabled, and an enrolled fleet using Automated Device Enrolment via ABM.
  • A deployed configuration profile containing the com.apple.security.FDERecoveryKeyEscrow payload, scoped to all managed Macs, so that personal recovery keys generated locally are automatically redirected to the MDM server.
  • Jamf Pro API role with Read on Computers and Computer Inventory, plus Update permission scoped to a dedicated API client (not an admin’s personal account) for the compliance query script.
  • Script deployment capability: a Jamf Pro policy with a custom script payload, or an Intune Shell Script configuration profile with the Run as, and Run script as signed-in user options set to root.
  • A device is only in scope for remediation if fdesetup status reports FileVault as On. Never target unencrypted Macs; that is a separate enablement workflow.
  • Local admin execution context: the remediation script must run as root during a check-in or Self Service session while a volume owner with a valid Secure Token is logged in, per Apple’s documented FileVault deployment behaviour.

#Implementation Steps

  1. Deploy the recovery key redirection profile. Action: push a configuration profile containing the com.apple.security.FDERecoveryKeyEscrow payload to all managed Macs via Jamf Pro Configuration Profiles or an Intune custom profile. Expected result: every Mac that later generates or rotates a personal FileVault key automatically transmits it to the MDM server instead of only displaying it locally. Evidence: profile shows as “Installed” in device inventory; profiles show output on a test Mac lists the FDERecoveryKeyEscrow payload identifier.
  2. Deploy an inventory Extension Attribute (Jamf) or custom compliance script (Intune). Action: create a script-based Extension Attribute that checks local FileVault state and profile presence, and report the result at every inventory update. Expected result: every managed Mac contributes a fresh status string on each check-in cycle. Evidence: the Extension Attribute value populates in the computer inventory record within one check-in cycle of deployment.
  3. Build the server-side compliance query. Action: run a scheduled script against the Jamf Pro API computers-inventory endpoint, filtering on the diskEncryption.individualRecoveryKeyValidityStatus field for values other than VALID. Expected result: a machine-readable list of Macs with missing, unknown, or invalid escrowed keys. Evidence: script output log with serial numbers and status values, timestamped.
  4. Scope a Smart Group (Jamf) or dynamic device group (Intune) to the non-compliant population. Action: build a Smart Group using the Extension Attribute value “Escrow Profile Missing” or “Key Status Unknown”. Expected result: the group membership updates automatically as devices drift in and out of compliance. Evidence: Smart Group membership count visible in Jamf Pro console, matching the API query result count within one inventory cycle.
  5. Deploy the remediation policy. Action: scope a Jamf Pro policy (or Intune shell script assignment) containing the rotation script to the non-compliant Smart Group, triggered on check-in with a frequency of “once per day until it runs successfully”. Expected result: the personal recovery key is regenerated and re-escrowed without user interaction. Evidence: policy log shows exit code 0; local remediation log file shows a successful rotation timestamp.
  6. Fire a webhook notification on remediation outcome. Action: the remediation script posts a JSON payload to a monitoring webhook (Slack, Teams, or a ticketing system’s inbound API) reporting success or failure. Expected result: a real-time signal lands in the operations channel without anyone opening the MDM console. Evidence: webhook delivery log entry with HTTP 200 response and matching serial number.
  7. Re-verify escrow status. Action: re-run the compliance query 24 hours after remediation to confirm the device has moved from a non-compliant to a compliant state. Expected result: individualRecoveryKeyValidityStatus reads VALID for the remediated serial number. Evidence: diff of the before/after API query output showing the status transition.

#Detection Extension Attribute Script

Deploy this as a Jamf Pro Extension Attribute (script input type) so escrow health becomes a queryable inventory field rather than something a technician has to remember to check manually.

1#!/bin/bash
2# Extension Attribute: FileVault Escrow Health
3# Reports whether FileVault is on and whether the redirection
4# profile that forces personal key escrow to MDM is installed.
5
6FV_STATUS=$(fdesetup status)
7PROFILE_COUNT=$(profiles show -output stdout-xml 2>/dev/null | grep -c "com.apple.security.FDERecoveryKeyEscrow")
8
9if [[ "$FV_STATUS" != *"FileVault is On"* ]]; then
10  echo "<result>FileVault Not Enabled</result>"
11elif [[ "$PROFILE_COUNT" -eq 0 ]]; then
12  echo "<result>Escrow Profile Missing</result>"
13else
14  echo "<result>Escrow Profile Present</result>"
15fi

Expected output on a healthy Mac: Escrow Profile Present. On a Mac missing the redirection profile: Escrow Profile Missing, which should immediately place it in the remediation Smart Group.

#Server-Side Compliance Query

This script queries the Jamf Pro API for the authoritative, server-verified escrow status. Local checks confirm the profile is installed; only the server can confirm the key actually arrived and validated.

1import requests
2
3JAMF_URL = "https://yourinstance.jamfcloud.com"
4CLIENT_ID = "YOUR_API_CLIENT_ID"
5CLIENT_SECRET = "YOUR_API_CLIENT_SECRET"
6
7def get_token():
8    resp = requests.post(
9        f"{JAMF_URL}/api/oauth/token",
10        data={
11            "grant_type": "client_credentials",
12            "client_id": CLIENT_ID,
13            "client_secret": CLIENT_SECRET,
14        },
15        timeout=30,
16    )
17    resp.raise_for_status()
18    return resp.json()["access_token"]
19
20def find_noncompliant(token):
21    headers = {"Authorization": f"Bearer {token}", "Accept": "application/json"}
22    params = {
23        "page": 0,
24        "page-size": 200,
25        "section": "DISK_ENCRYPTION,GENERAL",
26    }
27    resp = requests.get(
28        f"{JAMF_URL}/api/v1/computers-inventory",
29        headers=headers,
30        params=params,
31        timeout=30,
32    )
33    resp.raise_for_status()
34    results = []
35    for device in resp.json().get("results", []):
36        status = device.get("diskEncryption", {}).get(
37            "individualRecoveryKeyValidityStatus", "UNKNOWN"
38        )
39        if status != "VALID":
40            results.append(
41                {
42                    "serialNumber": device["general"]["serialNumber"],
43                    "name": device["general"]["name"],
44                    "status": status,
45                }
46            )
47    return results
48
49if __name__ == "__main__":
50    token = get_token()
51    noncompliant = find_noncompliant(token)
52    for item in noncompliant:
53        print(item)

Expected output for a fleet with two problem devices: two dictionary lines printed, each containing a serial number and a status of INVALID or UNKNOWN. An empty output means the fleet is fully compliant.

#Remediation Script

Deploy this via a Jamf policy or an Intune shell script scoped only to the non-compliant group. It rotates the personal recovery key, which forces the redirection profile to push the new key to the MDM server immediately.

1#!/bin/bash
2# FileVault Recovery Key Remediation
3# Scope: devices flagged with Escrow Profile Missing or invalid key status
4LOGFILE="/var/log/filevault-key-remediation.log"
5TIMESTAMP=$(date "+%Y-%m-%d %H:%M:%S")
6
7FV_STATUS=$(fdesetup status)
8
9if [[ "$FV_STATUS" != *"FileVault is On"* ]]; then
10  echo "$TIMESTAMP SKIP: FileVault not enabled on this device" >> "$LOGFILE"
11  exit 1
12fi
13
14# Rotate the personal recovery key. The redirection profile installed
15# in Step 1 forces the new key to escrow to the MDM server automatically.
16ROTATE_OUTPUT=$(fdesetup changerecovery -personal -outputplist 2>&1)
17ROTATE_EXIT=$?
18
19if [[ "$ROTATE_EXIT" -eq 0 ]]; then
20  echo "$TIMESTAMP SUCCESS: recovery key rotated, awaiting escrow confirmation" >> "$LOGFILE"
21else
22  echo "$TIMESTAMP FAILURE: $ROTATE_OUTPUT" >> "$LOGFILE"
23fi
24
25exit "$ROTATE_EXIT"

Expected output in the log file on success: SUCCESS: recovery key rotated, awaiting escrow confirmation. A non-zero exit code should trigger the webhook failure branch described below rather than being silently retried indefinitely.

#Webhook Notification Payload

Append this call to the end of the remediation script so operations channels get a real-time signal instead of relying on someone opening the console.

1curl -s -X POST "https://hooks.example.com/services/ops-alerts" 
2  -H "Content-Type: application/json" 
3  -d '{"text":"FileVault key remediation event","serialNumber":"'"$(system_profiler SPHardwareDataType | awk '/Serial/{print $4}')"'","status":"'"$ROTATE_EXIT"'","timestamp":"'"$TIMESTAMP"'"}'

Example JSON body received by the webhook endpoint:

1{
2  "text": "FileVault key remediation event",
3  "serialNumber": "C02XG1234ABC",
4  "status": "0",
5  "timestamp": "2024-05-01 09:14:02"
6}

#Verification and Expected Evidence

CheckMethodExpected Evidence
Profile installedprofiles show on deviceFDERecoveryKeyEscrow payload identifier listed
Local FileVault stateExtension Attribute value in inventory“Escrow Profile Present”
Server-side key validityJamf Pro API computers-inventory queryindividualRecoveryKeyValidityStatus equals VALID
Remediation executionPolicy log or Intune script run statusExit code 0, log entry with SUCCESS string
AlertingWebhook delivery logHTTP 200 response matching device serial number

#Rollback

Recovery key rotation is non-destructive: it does not touch encrypted data, does not require a reboot, and does not remove the existing institutional key if one is present. There is no data to roll back. If the redirection profile itself causes unexpected behaviour, such as conflicting with an existing institutional key deployment, remove the MDM configuration profile from the scope and unscope the remediation policy from the affected group. If a specific Mac reports repeated rotation failures, the safe rollback path is to fall back to the manual key retrieval process for that single device while it is investigated, rather than disabling the automation fleet-wide.

#Failure and Escalation Conditions

  • The remediation script returns a non-zero exit code on two consecutive scheduled runs for the same serial number: escalate to L2 to check Secure Token and bootstrap token status with diskutil apfs listUsers /.
  • The Jamf Pro API query returns individualRecoveryKeyValidityStatus as UNKNOWN for more than 5 percent of the fleet after 48 hours: escalate to the MDM platform owner, since this points at a systemic escrow pipeline issue rather than individual device drift.
  • A user reports a lockout and the escrowed key on file fails validation when tested against the device: this is the one condition that should wake a human technician immediately, regardless of time of day, since the user has no other path back into the device short of erase and reinstall.
  • The webhook endpoint stops receiving events for more than one check-in cycle: treat as a monitoring blind spot and escalate to whoever owns the alerting integration, not the FileVault workflow itself.

#Measuring Ticket Deflection

Baseline the current volume of FileVault unlock and recovery key tickets over a rolling 90-day window before deployment. After rollout, track three numbers monthly: the count of devices in the non-compliant Smart Group at the start of each month, the percentage that self-remediate within one check-in cycle without a ticket being opened, and the count of tickets that still required manual key retrieval. A healthy deployment should show the non-compliant population trending toward zero and manual retrieval tickets dropping by at least 70 percent within the first full quarter, since the majority of prior tickets were caused by silent escrow failures rather than genuine user error.

#Blast Radius and Monitoring Signal

The blast radius of the remediation script is limited to key rotation on individually scoped, already-FileVault-enabled Macs; it never enables encryption on an unencrypted device and never modifies an institutional key. The monitoring signal to watch is the daily count of devices leaving the non-compliant Smart Group compared to the count entering it; a net positive inflow over several days indicates the redirection profile itself has stopped deploying correctly and needs review before the remediation script is blamed.

#References

For the underlying platform behaviour and API fields referenced in this workflow, see the Apple Platform Deployment Guide for FileVault and configuration profile management, and the Apple Developer documentation for Device Management payloads, which defines the FileVault recovery key escrow payload used in Step 1. For platform-specific implementation detail, consult the Jamf Pro documentation for FileVault 2 management and the Microsoft Intune documentation for macOS shell scripts if deploying the remediation logic through Intune instead of Jamf Pro.

Sources and verification

Vendor documentation and external technical references used by this playbook.

Advanced suggested reading

Ready to go deeper?

These articles come from KBY’s senior engineering editorial. Expect denser architecture, fewer introductory explanations and deeper production trade-offs.

Leaving Ops Playbook
Reader Interaction

Comments

Add a thoughtful note on Auto-Remediating FileVault Recovery Key Escrow Failures. Comments are checked for spam and held for moderation before appearing.

Loading comments...

Loading anti-spam check...