Booting macOS on Apple silicon: LocalPolicy

This is the first of a couple of articles looking in detail at how starting up an Apple silicon Mac is controlled, to bring understanding to problems creating bootable external disks, and how to tackle them.

Apple silicon Macs are designed to boot as securely as possible, which would require exclusion of all third-party kernel extensions, full System Integrity Protection (SIP), and more besides. Recognising that many Macs simply can’t be used like that, Apple gives the user control over the level of security to be used, in Startup Security Utility, in Recovery mode. For this to work with boot volume groups (BVG), each BVG must have its own set of boot security policies, determined by its LocalPolicy.


LocalPolicy location

LocalPolicy is stored in folders in the iSCPreboot volume in the hidden Apple_APFS_ISC container of internal storage, but not on external bootable disks, in the path /System/Volumes/iSCPreboot/[BVG UUID]/LocalPolicy, where [BVG UUID] is known in the LocalPolicy as the Volume Group UUID. You may struggle to discover what that UUID is, but it’s apparently the same as the APFS file system UUID of the Data volume in that BVG. This incidentally explains the importance of the Data volume, as without its UUID there is no BVG, and why cloning a BVG could be hazardous if it also duplicated the UUID of the Data volume.

LocalPolicy is a collection of settings for Secure Boot, together with hashes for key items used during the boot process. These are stored, like much boot data, in an Image4 file, encoded in binary form in a format commonly used for security certificates. There should be separate LocalPolicy files for the normal boot volume and Recovery, although the latter is only created when the Mac has been booted from that paired Recovery volume.

Interestingly, with the advent of Ventura, alongside those LocalPolicy folders are new links to cryptexes and their contents, including the kernelcache for that volume. If you’re interested in exploring how Ventura uses cryptexes, those may repay further investigation.

Applying LocalPolicy

The selected boot disk, or more specifically the BVG to be used at the next boot, is saved to NVRAM. This is controlled by System Settings > General > Startup Disk, or in Recovery. There’s no option in Apple silicon Macs to change that on the fly once the boot process has started, as can be done from the EFI of an Intel Mac.

Early during the boot process, once the Boot ROM has verified the Low-Level Bootloader (LLB) stored in Flash memory, LLB discovers the intended boot volume from NVRAM, validates its LocalPolicy, then reads it from the iSCPreboot container on the internal SSD to determine Secure Boot settings for the designated BVG, and its key hashes. It next locates the Preboot volume in the BVG, decrypts and verifies iBoot (the second-stage) there, and hands over to that to continue the boot sequence. That’s summarised for booting from the internal SSD in the following diagram.


Inspecting LocalPolicy

You can inspect some settings in LocalPolicy in System Information > Hardware > Controller, but that’s only a short summary. The best way to see the full contents is using the command tool bputil.

bputil is one of the most hazardous command tools in macOS accessible to the user. Experimenting with it is guaranteed to cause your Mac serious problems. If you deviate from its two ‘safe’ command options, you are very likely to end up having to perform a full DFU restore of your Mac. Please use it extremely carefully. When used running in normal mode, all bputil commands require to be run with elevated privileges using sudo, although that isn’t necessary when it’s used in Terminal in Recovery mode, where you’re already the root user.

To inspect the current LocalPolicy for the active BVG, use
sudo bputil -d
If you want to extend that to include all currently mounted BVGs, use
sudo bputil -e
instead. If you make yourself a rule that the only options you’ll use with bputil are -d and -e, your Mac is safe.

Relevant fields shown in the result are:

  • OS Type: given as macOS, macOS (overriden) for a VM, or one true recoveryOS when in Recovery
  • OS Pairing Status: Not Paired, except when booted in a paired recoveryOS or a VM, when it becomes Paired
  • Pairing Integrity: Valid
  • Signature Type: BAA or Other for a VM
  • OS Version: this is given as an internal version number based on Darwin, but extended with the build number, e.g. 22.1.400.0.0,0
  • Volume Group UUID: the APFS file system UUID for the Data volume in the BVG
  • Cryptex1 Image4 Hash: given for Ventura, otherwise absent
  • Cryptex1 Generation: 3 or 4 in Ventura, otherwise absent
  • Security Mode: Full, Reduced, Permissive
  • 3rd Party Kexts Status: by default Disabled
  • User-allowed MDM Control: by default Disabled
  • DEP-allowed MDM Control: by default Disabled
  • SIP Status: by default Enabled
  • Signed System Volume Status: by default Enabled
  • Kernel CTRR Status: by default Enabled
  • Boot Args Filtering Status: by default Enabled.

Detailed listings of the contents of LocalPolicy files are given by Apple, and by the Asahi Linux project. Note that those haven’t yet been updated to reflect changes in Ventura, such as Cryptex1 entries. The addition of those to LocalPolicy suggests that LLB verifies cryptexes ready for iBoot to load them.

In the next article, I’ll describe how LocalPolicy works with multiple boot volume groups.