fleet icon indicating copy to clipboard operation
fleet copied to clipboard

Send clear passcode MDM command to iOS devices

Open ddribeiro opened this issue 9 months ago • 3 comments

  • customer-beatrix: Gong snippet: None.
  • @noahtalerman: User requested this because they want to remotely clear the passcode from a locked iOS device using Fleet, without needing to erase the device and risk data loss. Users can't run the ClearPasscode MDM command as a custom command because Fleet does not collect the required UnlockToken (due to the com.apple.mdm.token capability being missing from the enrollment profile).
    • @noahtalerman: Can we get that UnlockToken after enrollment?
      • @ddribeiro: I think we could redeliver the enrollment profile with the updated ServerCapabilities array, as long as the topic in the profile remains the same. I’m not 100% sure about this though.
    • @noahtalerman: Eventually Fleet could add the ability to retrieve the unlock token and allow admins to send a Clear Passcode command as a custom command or via the UI.

ddribeiro avatar Mar 28 '25 19:03 ddribeiro

Problem

As an IT admin with iOS devices enrolled into my Fleet server, I want to utilize the capability of the Apple MDM protocol to clear the passcode on a device in case the user it's assigned to forgets what it is. To do this, Fleet needs to send a "Clear the passcode" MDM command to the device, which has an UnlockToken property.

The unlock token is gathered by the MDM via a GetTokenRequest through the Check-in protocol. In order for the MDM server to collect this token, com.apple.mdm.token needs to be included in the ServerCapabilities key in the MDM enrollment profile. Fleet's enrollment profiles do not have this key by default.

What have you tried?

I tried to use the Fleet API to send a custom Clear the passcode MDM command, but I was not able to gather the Unlock Token for the device required to send the command.

Potential solutions

Fleet would be able to support sending clear passcode commands if it were able to retrieve the unlock token for each device.

Ideally, there would be a button in the Actions menu to clear the passcode so that an admin would not need to craft a custom MDM command.

What is the expected workflow as a result of your proposal?

An end user with an iPhone enrolled in Fleet would forget their passcode and not be able to get into their phone > They would contact IT for assistance > An IT admin would use Fleet to send a clear passcode command to the device > The end user would be able to access their device without needing to erase it (possibly preventing data loss) and set a new passcode.

noahtalerman avatar Apr 08 '25 21:04 noahtalerman

  • @noahtalerman: User requested this because they want to remotely clear the passcode from a locked iOS device using Fleet, without needing to erase the device and risk data loss. Users can't run the ClearPasscode MDM command as a custom command because Fleet does not collect the required UnlockToken (due to the com.apple.mdm.token capability being missing from the enrollment profile).
    • @noahtalerman: Can we get that UnlockToken after enrollment?

@ddribeiro can Fleet get the UnlockToken after enrollment? Or will the host, when we make changes to Fleet to get the UnlockToken, need to re-turn on MDM?

noahtalerman avatar Apr 08 '25 21:04 noahtalerman

Can Fleet get the UnlockToken after enrollment? Or will the host, when we make changes to Fleet to get the UnlockToken, need to re-turn on MDM?

I think we could redeliver the enrollment profile with the updated ServerCapabilities array, as long as the topic in the profile remains the same. I’m not 100% sure about this though.

ddribeiro avatar Apr 08 '25 21:04 ddribeiro

I didn't realize there wasn't gong snippet. Added it the gong snippet for customer-beatrix . This feature request is something that will be beneficial to the teams workflow greatly.

bettapizza avatar Aug 22 '25 18:08 bettapizza

@ddribeiro does this custom MDM command work today? https://github.com/fleetdm/fleet/issues/28135#issuecomment-3105613042

noahtalerman avatar Sep 08 '25 21:09 noahtalerman

In my testing, I wasn't able to get UnlockToken to populate in the database. I downloaded the profile with the Get manual enrollment profile API endpoint from my test server, then added the com.apple.mdm.token string to the ServerCapabilities array. This new profile was used to enroll a macOS host, but the Fleet database still shows NULL for the unlock_token.

mysql> SELECT id, serial_number, unlock_token FROM nano_devices;
+--------------------------------------+---------------+----------------------------+
| id                                   | serial_number | unlock_token               |
+--------------------------------------+---------------+----------------------------+
| C53FC6A4-30C3-57D4-8DB9-C68EC9161B19 | Z0KTD2QK3Q    | NULL                       |
| FF1DC48D-ED49-5A35-B331-429A643195E6 | ZYMT7G0DKM    | NULL                       |
+--------------------------------------+---------------+----------------------------+

It could be that these unlock tokens are only generated for iOS (since that's where they're used), but regardless, the MDM enrollment profile would need to be updated on existing devices to get this token to even populate in the database for those devices.

spalmesano0 avatar Sep 09 '25 21:09 spalmesano0

@noahtalerman fyi ^

zayhanlon avatar Sep 29 '25 17:09 zayhanlon

In my testing, I wasn't able to get UnlockToken to populate in the database. I downloaded the profile with the Get manual enrollment profile API endpoint from my test server, then added the com.apple.mdm.token string to the ServerCapabilities array. This new profile was used to enroll a macOS host, but the Fleet database still shows NULL for the unlock_token.

@spalmesano0 thanks for trying this!

As a follow up request, can you please try enrolling an iOS/iPadOS host exactly the same way customer-beatrix does?

We want to understand if beatrix has a workaround right now. Even if it's a really painful one in which they have to reach out to Customer Success to go into the Fleet DB to get the UnlockToken.

I'm not sure if beatrix automatically enrolls these hosts via Apple Business Manager (ABM) or manually enroll via profile from the /enroll page or both. The beatrix CSM may know. If it's via enrollment profile from the /enroll page, please don't edit the profile that Fleet provides today.

It could be that these unlock tokens are only generated for iOS (since that's where they're used)

You could be right about this. The ClearPasscode command is only available for iOS/iPadOS:

Image

regardless, the MDM enrollment profile would need to be updated on existing devices to get this token to even populate in the database for those devices.

I'm not convinced the profile needs to change until we've tested this on an iOS host using the exact profile that Fleet uses today. It looks like @georgekarrv was able to get the token. Not sure if he modified the enrollment. profile.

noahtalerman avatar Sep 29 '25 23:09 noahtalerman

I'm not sure if beatrix automatically enrolls these hosts via Apple Business Manager (ABM) or manually enroll via profile from the /enroll page or both. The beatrix CSM may know. If it's via enrollment profile from the /enroll page, please don't edit the profile that Fleet provides today.

@bettapizza do you know how they are enrolling these devices?

spalmesano0 avatar Sep 30 '25 11:09 spalmesano0

Still waiting on an iOS test device, but beatrix confirmed they use ABM.

spalmesano0 avatar Oct 15 '25 18:10 spalmesano0

@noahtalerman got it to work with an iPad.

Here's the order of operations:

  1. Sign in to the mysql database
  2. Get the host info using SELECT id, serial_number, TO_BASE64(unlock_token) AS unlock_token_base64 FROM nano_devices;
  3. Use the base64 version of the unlock token in the UnlockToken key and a new UUID (uuidgen on macOS) to use for the CommandUUID key of the MDM command XML
  4. Encode that in base64 (cat clear_passcode.xml | base64)
  5. Send the command using our Run MDM command endpoint with the id from step 2 and the base64 version of the XML from step 4

If all went well, the response should be 200 OK:

{
    "command_uuid": "84F7F777-803E-40BB-8B47-2C0DC8B0118A",
    "request_type": "ClearPasscode",
    "platform": "darwin"
}

spalmesano0 avatar Oct 21 '25 21:10 spalmesano0

  • @spalmesano0: In the interim, customer-beatrix can reach out to Customer Success to help them clear the passcode. Here's the order of operations:
  1. Sign in to the mysql database
  2. Get the host info using SELECT id, serial_number, TO_BASE64(unlock_token) AS unlock_token_base64 FROM nano_devices;
  3. Use the base64 version of the unlock token in the UnlockToken key and a new UUID (uuidgen on macOS) to use for the CommandUUID key of the MDM command XML
  4. Encode that in base64 (cat clear_passcode.xml | base64)
  5. Send the command using our Run MDM command endpoint with the id from step 2 and the base64 version of the XML from step 4

If all went well, the response should be 200 OK:

{
    "command_uuid": "84F7F777-803E-40BB-8B47-2C0DC8B0118A",
    "request_type": "ClearPasscode",
    "platform": "darwin"
}

Nice! While that's not perfect that sounds like a great interim solution.

@bettapizza what do you think? Heads up that it requires customer-beatrix to reach out to CS.

I updated the issue description to capture the interim solution.

cc @zayhanlon

noahtalerman avatar Oct 22 '25 16:10 noahtalerman

Hey @noahtalerman , to clarify - they will need to reach out for the initial setup or for each clear the passcode request? @spalmesano0 would it be possible to make a video demo to share with customer-beatrix to share the interim solution?

bettapizza avatar Oct 22 '25 16:10 bettapizza

@spalmesano0 would it be possible to make a video demo to share with customer-beatrix to share the interim solution?

@bettapizza yes. Is this urgent for them?

spalmesano0 avatar Oct 22 '25 18:10 spalmesano0

@spalmesano0 - It's been a high priority ask.

bettapizza avatar Oct 22 '25 18:10 bettapizza

they will need to reach out for the initial setup or for each clear the passcode request?

@bettapizza I think they will need to reach out for every clear passcode request. Why? Currently, you can only access the unlock token if you have access to Fleet's database (DB): https://github.com/fleetdm/fleet/issues/27646#issuecomment-3433231344

It's not exposed in the UI/API yet.

@spalmesano0 please correct me if I'm wrong.

noahtalerman avatar Oct 23 '25 21:10 noahtalerman

When the database is accessed for the customer, we should be able to provide every unlock token at one time. But, if there are new devices that are enrolled later, they'd need to reach out again for those new tokens.

I'll have a demo video for this ready by end of tomorrow.

spalmesano0 avatar Oct 23 '25 22:10 spalmesano0

@bettapizza Took me a couple of tries to get the recording right, but here it is! 🙂 This link is only available to you and Matt for now.

Here's the example XML that I used in the video: clear_passcode.xml.

In case they don't want to use Postman, here's the command:

curl --location '$API_ENDPOINT' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer $API_TOKEN' \
--data '{
  "command": "$BASE64_PAYLOAD"
  "host_uuids": ["$UUID"]
}'

spalmesano0 avatar Oct 24 '25 19:10 spalmesano0

Thank you for the work on this @spalmesano0 !

bettapizza avatar Oct 24 '25 19:10 bettapizza

@spalmesano0 Can you write up a summary of your findings and assign this back to Noah so we can bring this through the feature request process?

ddribeiro avatar Nov 24 '25 17:11 ddribeiro

Summary:

  1. Customer requests unlock tokens from Fleet support.
  2. Customer runs through the steps outlined here.

spalmesano0 avatar Dec 01 '25 13:12 spalmesano0