Photo of Joe T. Sylve

Joe T. Sylve, Ph.D.

Digital Forensic Researcher and Educator

Volume Grafting

Volume grafting is a mechanism introduced in macOS 13 that mounts a disk image’s APFS contents as a subdirectory of an existing volume. This is the technology behind Cryptexes, the cryptographically sealed, graftable disk images used for Rapid Security Responses and system extensions. This post covers the graft lifecycle, constraints, and on-disk metadata.

Overview

A graft takes an APFS-formatted disk image file that resides on a host volume and mounts its file system tree under a designated directory on that same volume. To applications, the grafted content appears as ordinary files and directories within the host volume’s namespace. Up to 255 grafts can be active on a single volume simultaneously.

The kernel builds a blockmap LUT (lookup table) that maps logical block addresses within the graft image to physical blocks on the host volume’s storage. This allows the grafted file system to be read using the same block I/O path as the host volume.

Graft Constraints

Graft Extended Attributes

Three extended attributes on the graft file’s inode record the J-object ID reservation:

Name Size Description
com.apple.fs.graft-vol-uuid 16 bytes UUID of the host volume at graft time
com.apple.fs.graft-jobj-id-base 8 bytes Base (start) of the reserved J-object ID range
com.apple.fs.graft-jobj-id-len 8 bytes Length (count) of the reserved J-object ID range

These attributes are file-system-owned (XATTR_FILE_SYSTEM_OWNED) and persist after ungraft, allowing subsequent grafts of the same file to reclaim the same ID range without conflicts.

Graft Lifecycle

Phase 1: Validation

The kernel verifies that all constraints are met: the file exists, is not compressed, has no hard links, the directory is valid, and the volume has capacity for another graft.

Phase 2: Blockmap LUT Construction

The kernel iterates all data extents of the graft file and builds an in-memory B-Tree (subtype OBJECT_TYPE_GRAFT_BLOCKMAP_LUT_TREE) that maps logical blocks within the image to physical blocks on the host volume. If the file is a clone of an already-grafted file, the existing blockmap is shared.

Phase 3: Encryption

On encrypted volumes, the graft file’s encryption key is unwrapped and retained for later I/O translation.

Phase 4: Container and Volume Mount

The APFS container embedded in the graft image is mounted using the blockmap LUT for I/O translation. The first volume within the grafted container is then mounted.

Phase 5: Metadata LUT Enhancement

The blockmap is augmented with metadata block mappings (container superblock, checkpoint areas, space manager, object maps, B-Tree nodes). Metadata blocks are distinguished from data blocks by having bit 31 set in the LUT key.

Phase 6: Image4 Authentication

For sealed graft images (Cryptexes), the volume’s root hash is verified against an Image4 payload and manifest. Authentication volume types include:

Type Name Description
4 RSR Graft Rapid Security Response (authentication always required)
5 Strict Graft Authentication failure is fatal (kernel panic)

Phase 7: J-Object ID Range Reservation

A range of object identifiers is reserved from the host volume’s ID space for the grafted content. This ensures grafted inodes do not collide with host volume inodes. The reservation is persisted in the graft extended attributes.

Phase 8: State Registration

The graft state is registered, a synthetic device ID is generated, and grafted file-system vnodes are loaded. An IOKit AppleAPFSGraft service node is published.

Ungraft

The ungraft operation reverses the graft:

  1. Remove graft state and decrement the volume’s graft count
  2. Wait for all concurrent readers to drain
  3. Revoke vnodes belonging to the graft
  4. Detach the IOKit service node
  5. Unmount the grafted volume and container
  6. Clear graft-related inode flags on the directory and file
  7. Release crypto state if present

The ungraft ioctl supports flags for ungrafting all grafts on a volume (bit 0) and forcing ungraft even when vnodes are in use (bit 1).

Forensic Considerations

Conclusion

Volume grafting extends APFS’s capabilities by allowing sealed disk images to be mounted as subdirectories. Combined with Image4 authentication, this provides a secure mechanism for distributing system extensions and security updates (Cryptexes) without breaking the sealed system volume’s integrity guarantees.

Find an issue or technical inaccuracy in this post? Please file an issue so that it may be corrected.