Thanks for being a part of WWDC25!

How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here

FSKit module mount fails with permission error on physical disks

I'm trying to make an FSKit module for NTFS read-write filesystem and at the stage where everything is more or less working fine as long as I mount the volume via mount -F and that volume is a RAM disk. However, since the default NTFS read-only driver is already present in macOS, this introduces an additional challenge.

Judging by the DiskArbitration sources, it looks like all FSKit modules are allowed to probe anything only after all kext modules. So, in this situation, any third-party NTFS FSKit module is effectively blocked from using DiskArbitration mechanisms at all because it's always masked during the probing by the system's read-only kext.

This leaves mount -F as the only means to mount the NTFS volume via FSKit. However, even that doesn't work for volumes on real (non-RAM) disks due to permission issues. The logs in Console.app hint that the FSKit extension is running; however, it looks like the fskitd itself doesn't have permissions to access real disks if it's initiated from the mount utility?

default	16:42:41.939498+0200	fskitd	New module list <private>
default	16:42:41.939531+0200	fskitd	Old modules (null)
default	16:42:41.939578+0200	fskitd	Added 2 identifiers: <private>
default	16:42:41.939651+0200	fskitd	[0x7fc58020bf00] activating connection: mach=true listener=true peer=false name=com.apple.filesystems.fskitd
debug	16:42:41.939768+0200	fskitd	main:RunLoopRun
debug	16:42:41.939811+0200	fskitd	-[liveFilesMountServiceDelegate listener:shouldAcceptNewConnection:]: start
default	16:42:41.939870+0200	fskitd	Incomming connection, entitled 0
debug	16:42:41.940021+0200	fskitd	-[liveFilesMountServiceDelegate listener:shouldAcceptNewConnection:]: accepting connection
default	16:42:41.940048+0200	fskitd	[0x7fc580006120] activating connection: mach=false listener=false peer=true name=com.apple.filesystems.fskitd.peer[1816].0x7fc580006120
default	16:42:41.940325+0200	fskitd	Hello FSClient! entitlement no
default	16:42:41.940977+0200	fskitd	About to get current agent for 503
default	16:42:41.941104+0200	fskitd	[0x7fc580015480] activating connection: mach=true listener=false peer=false name=com.apple.fskit.fskit_agent
info	16:42:41.941227+0200	fskitd	About to call to fskit_agent
debug	16:42:42.004630+0200	fskitd	-[fskitdAgentManager currentExtensionForShortName:auditToken:replyHandler:]_block_invoke: Found extension for fsShortName (<private>)
info	16:42:42.005409+0200	fskitd	Probe starting on <private>
debug	16:42:42.005480+0200	fskitd	-[FSResourceManager getResourceState:]:not_found:<private>
debug	16:42:42.005528+0200	fskitd	-[FSResourceManager addTaskUUID:resource:]:<private>: Adding task (<private>)
debug	16:42:42.005583+0200	fskitd	applyResource starting with resource <private> kind 1
default	16:42:42.005609+0200	fskitd	About to get current agent for 503
info	16:42:42.005629+0200	fskitd	About to call to fskit_agent
debug	16:42:42.006700+0200	fskitd	-[fskitdXPCServer getExtensionModuleFromID:forToken:]_block_invoke: Found extension <private>, attrs <private>
default	16:42:42.006829+0200	fskitd	About to get current agent for 503
info	16:42:42.006858+0200	fskitd	About to call to fskit_agent, bundle ID <private>, instanceUUID <private>
default	16:42:42.070923+0200	fskitd	About to grab assertion on pid 1820
default	16:42:42.071058+0200	fskitd	Initializing connection
default	16:42:42.071141+0200	fskitd	Removing all cached process handles
default	16:42:42.071185+0200	fskitd	Sending handshake request attempt #1 to server
default	16:42:42.071223+0200	fskitd	Creating connection to com.apple.runningboard
info	16:42:42.071224+0200	fskitd	Acquiring assertion: <RBSAssertionDescriptor| "com.apple.extension.session" ID:(null) target:1820>
default	16:42:42.071258+0200	fskitd	[0x7fc58001cdc0] activating connection: mach=true listener=false peer=false name=com.apple.runningboard
default	16:42:42.075617+0200	fskitd	Handshake succeeded
default	16:42:42.075660+0200	fskitd	Identity resolved as osservice<com.apple.filesystems.fskitd>
debug	16:42:42.076337+0200	fskitd	Adding assertion 183-1817-1669 to dictionary
debug	16:42:42.076385+0200	fskitd	+[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]:bsdName:<private>
default	16:42:42.076457+0200	fskitd	[0x7fc5801092e0] activating connection: mach=true listener=false peer=false name=com.apple.fskit.fskit_helper
default	16:42:42.077706+0200	fskitd	+[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]_block_invoke: Open device returned error Error Domain=NSPOSIXErrorDomain Code=13
info	16:42:42.077760+0200	fskitd	+[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]: failed to open device <private>, Error Domain=NSPOSIXErrorDomain Code=13
default	16:42:42.077805+0200	fskitd	[0x7fc5801092e0] invalidated because the current process cancelled the connection by calling xpc_connection_cancel()
debug	16:42:42.077830+0200	fskitd	+[FSBlockDeviceResource(Project) openWithBSDName:writable:auditToken:replyHandler:]:end
info	16:42:42.078459+0200	fskitd	openWith returned err Error Domain=NSPOSIXErrorDomain Code=13 dev (null)
error	16:42:42.078501+0200	fskitd	-[fskitdXPCServer getRealResource:auditToken:reply:]: Unable to convert proxy FSBlockDeviceResource into open resource
error	16:42:42.078538+0200	fskitd	-[fskitdXPCServer applyResource:targetBundle:instanceID:initiatorAuditToken:authorizingAuditToken:isProbe:usingBlock:]: Can't get the real resource of <private>
default	16:42:42.105443+0200	fskitd	[0x7fc580006120] invalidated because the client process (pid 1816) either cancelled the connection or exited

The mount utility call I use is the same for RAM and real disks with the only difference being the device argument and this permission error is only relevant for real disks case.

So, the proper solution (using DiskArbitration) seems to be blocked architecturally in this use case due to FSKit modules being relegated to the fallback role. Is this subject to change in the future?

The remaining workaround with using the mount directly doesn't work for unclear reasons. Is that permission error a bug? Or am I missing something?

FSKit module mount fails with permission error on physical disks
 
 
Q