Is there a supported per-boot identifier that can't be reset or rolled back by a backup restore?

I'm looking for a documented, supported way for an iOS app to tell, on-device and without network access, that the device has restarted or been restored from a backup since a given point. The goal is to fail closed after either event. It is not to identify the device or user, and the value would never leave the device.

I'm aware of the existing forum guidance (for example thread 110044 and thread 809339), which describes best-effort techniques. I'm asking whether a guaranteed mechanism exists. Specifically, does iOS provide a supported public API, or a documented combination of APIs, that offers all of the following:

  1. Unique per boot. A value guaranteed never to repeat across boots of the same device. This would cover every kind of restart: graceful shutdown, forced or watchdog reset, kernel panic, and power loss or battery depletion.
  2. Not resettable or rolled back. A value the app itself cannot reset, that deleting and reinstalling the app doesn't reset, and that restoring a backup can neither reset nor roll back to an earlier value.
  3. Changes on every same-device restore. A signal guaranteed to change observably whenever a backup is restored to the same physical device, from iCloud Backup or an encrypted Finder backup, with or without Erase All Content and Settings first. It must not be stored in, derived from, or rolled back by anything a backup restores.

If no such API exists, it would help to know that too. And if some of these properties hold only as current implementation behavior rather than a documented guarantee, I'd appreciate knowing which.

Thanks!

Answered by DTS Engineer in 911990022
Written by fbratchettt in 853098021

I'm aware of the existing forum guidance (for example thread 110044 and thread 809339), which describes best-effort techniques.

That second thread references this reply, which I consider to be a reasonable way to detect restarts.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Written by fbratchettt in 853098021

I'm aware of the existing forum guidance (for example thread 110044 and thread 809339), which describes best-effort techniques.

That second thread references this reply, which I consider to be a reasonable way to detect restarts.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks, Quinn. I appreciate the clarification and the pointer to your POSIX semaphore guidance.

I understand that the semaphore approach is a reasonable best-effort restart detector.

My remaining question is specifically about supported guarantees rather than practical reliability.

Does Apple document any public mechanism that guarantees all three properties?

  1. A value or signal unique to every device boot.
  2. A value the app cannot reset and a backup restore cannot roll back.
  3. An observable change across every same-device backup restore, including restores that preserve existing device state.

I understand that the semaphore technique relies on a reasonable cleanup assumption rather than an explicitly documented guarantee.

If no public API provides these properties, confirmation of that limitation would also be helpful.

Thanks again!

I’ve responded to the above on that other thread, just to keep the discussion centralised.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Quinn was focused on the time issue, but I wanted to comment on this:

An observable change across every same-device backup restore

The simplest solution is to create a file and mark it with the "do not backup" attribute. If that file exists, then the device has not been restored. Note that if you use this approach, make sure that you're checking whether or not the file exists, NOT just attempting to access the file contents. File protection can prevent reading the data, and there’s a long history of apps assuming the file did not exist when the actual issue was file protection.

If you want an additional "defense in depth,” then you can also create a keychain entry that uses one of the "ThisDeviceOnly" access variants. Device restores from local encrypted backups will preserve this key, but keys stored with this property CANNOT be decrypted on any other device, making cross-device propagation impossible.

Finally, you can use the contents of the file to bind the keychain entry and file to each other. For example, you can use your keychain key to encrypt data which you then store in the backup file. Decrypting and validating that data then "proves" you’re on the same device that originally created the file.

The combination of all those elements means that the only way you'd fail to detect a restore would be if:

  1. The device had been compromised to the point where it was possible to reverse the do not backup attribute setting on your file.

  2. The device was then backed up and restored through an iTunes Encrypted backup.

  3. The backup was being restored onto the EXACT device which was previously backed up.

That's not necessarily impossible, but it's certainly not straightforward and, more importantly, those circumstances are SO narrow that I'm not sure why missing this particular case would actually be an issue.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware