Checking bootable systems using bputil on Apple silicon

Apple silicon Macs are designed to boot as securely as possible, requiring the exclusion of all third-party kernel extensions, full System Integrity Protection (SIP), and more. 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. For this to work with boot volume groups (BVGs), each must have its own set of boot security policies, determined by its LocalPolicy.

Without a valid LocalPolicy, Apple silicon Macs will refuse to boot from what would otherwise be a bootable BVG. This article extends my previous account of what makes a disk bootable by explaining more about LocalPolicy, and how you can use the command tool bputil to check it.

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.

LocalPolicy is created when installing macOS to an external disk, when the boot volume group on that disk is assigned its Owner. It can also be created when selecting the boot volume group on a bootable external disk to be the startup disk, if it doesn’t already have a valid LocalPolicy, for example when you want to boot from an external disk previously created using another Mac. This is commonly the point at which failure occurs.

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.

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 options, you’re likely to end up having to perform a full DFU restore of your Mac. When used running in normal mode, all bputil commands require elevated privileges using sudo, although that isn’t necessary 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.

Relevant fields shown in the result are:

OS Type: given as macOS, macOS (overriden) for a VM, one true recoveryOS when in paired recovery, or ordinary recovery OS when in fallback 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 and later, otherwise absent
Cryptex1 Generation: 3 or greater in Ventura and later, 17 in Sonoma (except for VMs which remain at 3), 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 been updated to reflect changes in Ventura, such as Cryptex1 entries.