Post

Replies

Boosts

Views

Activity

Sandboxed app cannot place File Provider placeholder file URLs on the pasteboard (sandbox error -20)
I'm building a sandboxed macOS app (Developer ID, App Sandbox enabled) with a File Provider extension that exposes on-demand placeholder files under  ~/Library/CloudStorage/<domain>/ . Expected: The app writes the placeholder file URLs to  NSPasteboard.general . The user presses ⌘V in Finder, and Finder fetches the contents on demand via  fetchContents . Observed: • Finder's own copy and paste of the same placeholders works, and  fetchContents  is called at paste time as expected. • When the sandboxed app writes the URLs to the pasteboard,  CFPasteboard  logs:  Sandbox extension creation failed ... (error -20) . The paste does not happen. • Writing  NSPasteboardItem  with  .fileURL  strings instead of  NSURL  objects produces the same error. • Adding  com.apple.security.temporary-exception.files.absolute-path.read-only  for the CloudStorage domain path fixes it. Questions: Is there a supported way for a sandboxed app to put File Provider placeholder URLs on the pasteboard without the temporary-exception entitlement? Is the temporary-exception entitlement acceptable for Mac App Store distribution, or is it only viable for Developer ID builds? Should the app grant itself access another way, for example through a security-scoped bookmark or by using  NSFileProviderManager  APIs?
3
0
197
23h
Installing a macOS guest onto an external USB disk with Virtualization.framework (sandboxed app)
Hello, We develop a sandboxed Mac App Store app that runs virtual machines with Virtualization.framework on Apple silicon (macOS 27). Users want to install a macOS guest onto an external USB disk and start the VM from it, so they can keep a VM on portable storage or on a disk larger than the Mac's internal drive. What we tried USB passthrough: we attach the disk before the VM starts, with VZUSBPassthroughDeviceConfiguration (from an AAUSBAccessory) on a VZXHCIControllerConfiguration. Linux guests install onto the disk and boot from it without problems. For a macOS guest, VZMacOSInstaller fails to start when the USB disk is the only storage: As we understand it, a macOS VM can only start from its own storage devices, never from a USB device, so even a successful install would not boot. VZDiskBlockDeviceStorageDeviceAttachment: this needs an open file handle to /dev/diskN. That requires admin rights, which a sandboxed app can't obtain, so we can't use it in our App Store app. Questions Is there a supported way to install a macOS guest onto an external USB disk and start the VM from it? Is there a sandbox-compatible way to get a VZDiskBlockDeviceStorageDeviceAttachment for an external disk, for example after user consent, similar to how AccessoryAccess grants USB devices? If neither is possible today, is support for this planned, or is there a recommended alternative? Thank you for any guidance.
2
0
52
1d
AccessoryAccess in a sandboxed helper: IOUSBHostInterface fails without a temporary-exception entitlement. Is there a supported way?
Hello, We are building USB passthrough for virtual machines on macOS 27 and would appreciate guidance from the AccessoryAccess / IOUSBHost / App Sandbox teams on the supported way to open a USB accessory's interfaces from a sandboxed helper process. WHAT WE ARE BUILDING Our app is a sandboxed macOS app that runs virtual machines. For guests that use Virtualization.framework, USB passthrough already works through VZUSBPassthroughDevice, using the AAUSBAccessory we get from AccessoryAccess. For a second kind of guest we use our own virtual machine monitor, built on Hypervisor.framework. Each VM runs in its own helper process, a nested app bundle in Contents/Helpers that the main app launches with Process. The helper's entitlements are: com.apple.security.app-sandbox = true com.apple.security.inherit = true com.apple.security.hypervisor = true com.apple.vm.networking = true The main app's entitlements include: com.apple.security.app-sandbox = true com.apple.developer.accessory-access.usb = true com.apple.security.device.usb = true (plus hypervisor, networking, files, application groups) The helper emulates an xHCI controller for the guest and forwards the guest's USB transfers to the real device. We use the same AccessoryAccess hand-off the documentation describes for worker processes: The main app registers an AAUSBAccessoryListener with AAUSBAccessoryManager and shows the consent UI. Nothing changed here from the Virtualization.framework path. When the user attaches a device to a VM, the main app calls -[AAUSBAccessory createXPCRepresentation]. We send the bytes of that xpc_data object to the helper over our existing control channel. We use the bytes rather than an XPC connection because the representation contains only data, no Mach ports or file descriptors. The helper rebuilds the accessory with -[AAUSBAccessory initWithXPCRepresentation:] and calls -openWithServiceQueue:completionHandler:. This succeeds and returns an IOUSBHostDevice. In the IORegistry the device then has an AppleUSBHostFrameworkDeviceClient created by the helper. When the guest sends SET_CONFIGURATION, the helper calls -[IOUSBHostDevice configureWithValue:matchInterfaces:NO error:], which succeeds. It then finds the device's IOUSBHostInterface children in the IORegistry and opens each one with -[IOUSBHostInterface initWithIOService:options:queue:error:interestHandler:]. Bulk and interrupt transfers then go through IOUSBHostPipe (copyPipeWithAddress:, enqueueIORequestWithData:...). THE PROBLEM Steps 1-3 work, and so do control requests on the default pipe. The guest enumerates the device and loads its driver. Step 4 fails: every interface fails to open with Failed to create IOUSBHostInterface. (kIOReturnInternalError, 0xe00002c9) With no interfaces open there are no pipes, so the guest's driver fails as soon as it moves data. A USB flash drive reported "This device cannot start (Code 10)", and a USB Ethernet adapter reported "Network cable unplugged". What we found: An unsandboxed command-line tool, run while the helper held the device through AccessoryAccess, opened the same IOUSBHostInterface with no error. The IORegistry then showed an AppleUSBHostFrameworkInterfaceClient under the interface, created by that tool. So the kernel and the accessory state allow the open; the App Sandbox blocks it. /System/Library/Sandbox/Profiles/application.sb contains: (when (entitlement "com.apple.security.device.usb") (allow iokit-open-user-client (iokit-user-client-class "IOUSBDeviceUserClientV2" "IOUSBInterfaceUserClientV3"))) com.apple.security.device.usb (which the app has) therefore covers only the legacy IOUSBLib user clients, not AppleUSBHostFrameworkInterfaceClient, the class IOUSBHostInterface uses. We found no rule for AppleUSBHostFrameworkDeviceClient either. We assume AccessoryAccess authorizes the device client when the accessory is opened, but nothing does the same for the accessory's interfaces. Adding com.apple.security.device.usb to the helper itself doesn't work: the helper is killed at launch (exit status 5). We understand an inherited-sandbox helper may carry only a limited set of entitlements. HOW WE WORKED AROUND IT We added this entitlement to the main app. The helper inherits the app's sandbox, so it gets the exception too: <key>com.apple.security.temporary-exception.iokit-user-client-class</key> <array> <string>AppleUSBHostFrameworkInterfaceClient</string> </array> With it, the helper opens the interfaces and passthrough works: the flash drive mounts in the guest, and the Ethernet adapter gets a DHCP address and passes traffic. We would rather not ship a temporary-exception entitlement, especially since we also distribute through the Mac App Store. QUESTIONS Is opening an accessory's interfaces with IOUSBHostInterface the intended way to do I/O on a device obtained through AccessoryAccess? If so, what is the supported way to authorize AppleUSBHostFrameworkInterfaceClient for a sandboxed process, or a helper inheriting its sandbox, without a temporary exception? Does AccessoryAccess grant access to an accessory's interfaces as well as the IOUSBHostDevice? For example, should a listener registered with interface matching criteria (AAUSBAccessoryMatchingCriteria initWithDeviceMatchingDictionary: interfaceMatchingDictionaries:...) be able to open those interfaces? Or is there an API we missed that returns IOUSBHostInterface or IOUSBHostPipe objects for an opened accessory? Is passing the accessory to a helper as the bytes of -createXPCRepresentation, instead of through an XPC connection, supported? The documentation describes the representation as something sent "via XPC". Our helpers are plain child processes, not XPC services. Should we use the legacy IOUSBLib interface API instead (IOUSBInterfaceInterface through IOCreatePlugInInterfaceForService, client class IOUSBInterfaceUserClientV3, which com.apple.security.device.usb allows)? Is that supported for a device AccessoryAccess has opened for exclusive access, and is it acceptable to mix IOUSBHostDevice from AccessoryAccess with IOUSBLib interface objects for the same device? Would the temporary-exception entitlement above be accepted in App Store review for this case, or should we file a Feedback Assistant request for a dedicated entitlement or an API change? Environment: macOS 27 (Golden Gate), Apple silicon Xcode with the macOS 27 SDK App and helper are signed with the same team; the helper is a nested app bundle in Contents/Helpers using com.apple.security.inherit Tested devices: a USB 3 flash drive (mass storage, Bulk-Only Transport) and a USB 2.5GbE Ethernet adapter (Realtek, vendor 0x0BDA, product 0x8156) We can provide a minimal sample project that reproduces the IOUSBHostInterface failure, plus IORegistry dumps. Thank you for your time.
8
0
494
5d
How can I set per-window titles in the Window menu for an iPad app running on Apple silicon Mac?
I’m developing a SwiftUI iPad app that runs on an Apple silicon Mac as an iPad app—not as a Mac Catalyst app. The app supports multiple windows, with each Live Screen window associated with a different virtual machine. In the macOS Window menu, all child windows appear as “VirtualProg” rather than showing their content or VM name. The Live Screen window is created from a data-driven  WindowGroup , roughly like this: WindowGroup(id: "vm-screen", for: String.self) { $vmName in VMScreenWindow(vmName: vmName) .navigationTitle(vmName.map { "Live ($0)" } ?? "Live Screen") } I’ve tried setting the title with  .navigationTitle  both on the  WindowGroup  content and inside the window’s  NavigationStack . I also tried setting  windowScene.title  on the specific scene obtained from  view.window?.windowScene  after the view controller appeared. Neither changed the Window-menu entries. Is there a supported way to set a per-window title for the macOS Window menu when running an iPad app on Mac? Does  UIScene.title  affect that menu, or only the window title bar and app switcher? Is this a limitation of the iPad-app-on-Mac runtime, or is there a recommended SwiftUI/UIKit lifecycle hook for this? I’m looking for a public API solution rather than private AppKit/window introspection.
4
1
810
1w
com.apple.vm.networking for helper binary
Hi everyone & DTS engineers, I am developing a macOS application that uses Apple's Virtualization framework and vmnet APIs. In my main application bundle, I have requested and received approval for the restricted entitlement com.apple.vm.networking. The main app works as expected with bridging/vmnet features. Now, I have embedded a command-line helper binary inside the app bundle (Contents/MacOS/). The helper is configured as follows: Set up with com.apple.security.app-sandbox = true Inherits App Sandbox rules (com.apple.security.inherit = true) Signed with com.apple.vm.networking = true in its entitlements file. However, when launching or invoking networking features from this helper binary, it fails to execute the expected vmnet functions / gets blocked at runtime. My questions for DTS / Apple Engineers: Since com.apple.vm.networking is a restricted entitlement tied to a specific App ID / Provisioning Profile, does an embedded CLI helper tool with its own Bundle ID need to be explicitly registered and granted this entitlement separately in the Developer Portal? If the helper uses com.apple.security.inherit, does AMFI still strictly evaluate the helper's own provisioning profile signature against com.apple.vm.networking independently of the main app bundle? What is the recommended architectural pattern for vmnet access when using helper tools—should network creation stay strictly in the main app process and communicate via XPC, or should the helper tool be granted its own matching profile and entitlement? Thanks in advance for any insight!
11
0
489
1w
Hypervisor.framework: guest RAM counted twice in phys_footprint after both host and guest write a page
Hello, I'm building a virtualization app on Hypervisor.framework (Apple silicon). Guest RAM is anonymous memory mapped with hv_vm_map. Activity Monitor and task_info(TASK_VM_INFO).phys_footprint show the VM process using much more memory than the guest is assigned. For example, a 6 GB Windows ARM64 guest shows about 8.6 GB. Here's what I've found: Pages written only from the host count once. Pages written only by the guest count once. A page written by both the host and the guest counts twice, even though it is the same physical page. The host reads back the guest's writes, so there's no second copy. In a real VM this happens all the time. The VM process writes into guest RAM for firmware loading, disk reads, virtio buffers and so on, and the guest writes the same pages. So the reported footprint keeps growing past the guest's RAM size. Minimal reproducer (needs the com.apple.security.hypervisor entitlement): // clang -O1 -o hvfootprint hvfootprint.c -framework Hypervisor // codesign -s - --entitlements hv.entitlements -f hvfootprint #include <Hypervisor/Hypervisor.h> #include <mach/mach.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #define MB (1024ull * 1024) #define GPA 0x40000000ull #define SIZE (2048 * MB) #define PAGE 16384 static uint64_t phys_footprint_mb(void) { task_vm_info_data_t info; mach_msg_type_number_t count = TASK_VM_INFO_COUNT; task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&info, &count); return info.phys_footprint / MB; } // Guest (EL1, MMU off): x0 = start GPA, x1 = value, x2 = page count. // Stores x1 to each 16 KB page, then exits with HVC. static const uint32_t guest_code[] = { 0xf9000001, // str x1, [x0] 0x91401000, // add x0, x0, #0x4000 0xf1000442, // subs x2, x2, #1 0x54ffffa1, // b.ne 0b 0xd4000002, // hvc #0 }; static void guest_write_all(hv_vcpu_t vcpu, uint64_t value) { hv_vcpu_set_reg(vcpu, HV_REG_PC, GPA); hv_vcpu_set_reg(vcpu, HV_REG_CPSR, 0x3c5); hv_vcpu_set_reg(vcpu, HV_REG_X0, GPA + PAGE); hv_vcpu_set_reg(vcpu, HV_REG_X1, value); hv_vcpu_set_reg(vcpu, HV_REG_X2, SIZE / PAGE - 1); hv_vcpu_run(vcpu); } int main(void) { uint8_t *ram = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); hv_vm_create(NULL); hv_vm_map(ram, GPA, SIZE, HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC); memcpy(ram, guest_code, sizeof(guest_code)); hv_vcpu_t vcpu; hv_vcpu_exit_t *exit_info; hv_vcpu_create(&vcpu, &exit_info, NULL); printf("start: phys_footprint %5llu MB\n", phys_footprint_mb()); for (uint64_t off = PAGE; off < SIZE; off += PAGE) // host writes every page ram[off] = 1; printf("host wrote 2 GB: phys_footprint %5llu MB\n", phys_footprint_mb()); guest_write_all(vcpu, 0x55); // guest writes the same pages printf("guest wrote the same 2 GB: phys_footprint %5llu MB\n", phys_footprint_mb()); printf("host sees guest data (same pages): %s\n", ram[PAGE] == 0x55 ? "yes" : "no"); guest_write_all(vcpu, 0x66); // and again printf("guest wrote the same 2 GB again: phys_footprint %5llu MB\n", phys_footprint_mb()); return 0; } Output (macOS 27.0.1, build 26A434, Apple M5): start: phys_footprint 2 MB host wrote 2 GB: phys_footprint 2050 MB guest wrote the same 2 GB: phys_footprint 4099 MB host sees guest data (same pages): yes guest wrote the same 2 GB again: phys_footprint 4099 MB 2 GB of shared guest RAM is reported as 4 GB. Other observations The result is the same whether guest RAM comes from mmap(MAP_PRIVATE | MAP_ANON), mmap(MAP_SHARED | MAP_ANON), mach_vm_allocate, or a named memory entry (mach_make_memory_entry_64 with MAP_MEM_NAMED_CREATE) mapped twice, with one view passed to hv_vm_map and the other used by the host. footprint region totals ("Footprint:" / Dirty) count only pages the host touched. When only the guest wrote 2 GB, the regions showed about 3 MB while phys_footprint showed 2,051 MB. So neither number shows real usage once both sides touch memory. System-wide anonymous memory (host_statistics64, internal_page_count + compressor_page_count) does not grow when the guest writes pages the host already wrote. That suggests this is accounting only, not a second physical copy. Parallels describes the same symptom for its VMs (https://kb.parallels.com/en/128437). Questions Is this double accounting expected for memory mapped with hv_vm_map, or is it a bug? If it's a bug, I'll file it in Feedback Assistant with this reproducer. Is there a supported way to allocate or map guest RAM so each physical page is charged to the process once? For example, a ledger tag, memory-entry ownership, or an hv_vm_map / hv_vm_allocate option. Is phys_footprint the right input for memory-pressure decisions (jetsam) for a VM process? Could the double count make such a process look larger than it is to the system? What is the recommended way to report a VM process's real memory use to users? Thank you.
2
0
359
2w
VZVirtualMachineView.automaticallyReconfiguresDisplay does not work for Golden Gate
I am using Virtualization framework for running Golden Gate VM in swift ui window with VZVirtualMachineView. i have set the automaticallyReconfiguresDisplay to true. but when i resize the window the resolution of Golden Gate does not change automatically to fit the window. This works fine for Tahoe. Golden Gate is not respecting the automaticallyReconfiguresDisplay. Any help in fixing this bug would be very helpful to me. Thanks in advance
6
0
810
3w
AAUSBAccessoryManager does not fire didconnect
Hi, I am trying to use AAUSBAccessoryManager with mac os 27 to connect host usb device to guest vm. here is my code // // USBPassthroughManager.swift // VirtualProg import AccessoryAccess import Foundation import IOKit @available(macOS 27.0, *) class USBPassthroughManager: NSObject, ObservableObject, AAUSBAccessoryListener { static let shared = USBPassthroughManager() @Published var availableDevices: [AAUSBAccessory] = [] func startListening() async { do { let existing = try await AAUSBAccessoryManager.shared .registerListener(self, matchingCriteria: []) await MainActor.run { self.availableDevices = existing } } catch { LogManager.shared.log(vmName: AppConstants.logGeneral, type: .error, message: "USB passthrough listener failed: \(error.localizedDescription)") } } func usbAccessoryDidConnect(_ usbAccessory: AAUSBAccessory) { DispatchQueue.main.async { guard !self.availableDevices.contains(where: { $0.registryID == usbAccessory.registryID }) else { return } self.availableDevices.append(usbAccessory) print(self.displayName(for: usbAccessory)) } } The usb icon in status bar menu is displayed and i can select the the usb device to connect to my app. the usb device is connected to my app. it is shown in the status bar. but usbAccessoryDidConnect is not firing. i have the entitlement com.apple.developer.accessory-access.usb in the capabilities. i get this in the xcode console start failed ((iokit/common) not permitted) for plugin for .......... and also disconnect is also not firing. Not sure what i am doing wrong. How can i determine the name of the USB Device from AAUSBAccessory. Any help would be appreciated. Thanks
8
1
837
Sep ’26
Programmatic IP Discovery for VZVirtualMachine in an App Store Sandbox
Hi everyone, I am developing a macOS virtualization manager (VirtualProg) using the Virtualization.framework. The application is distributed via the Mac App Store, so it operates strictly within the App Store Sandbox. I am looking for a reliable, programmatic way to discover the IP address assigned to a guest (both macOS and Linux). Is there a recommended "Sandbox-safe" API or pattern within the Virtualization framework—or a lower-level networking entitlement—that allows a host application to retrieve the guest's assigned IP address? Ideally, I am looking for a solution that does not require the user to manually install a non-sandboxed helper tool. Thanks in advance for any insights or guidance!
33
0
3.4k
Jun ’26
app groups user defaults are not returning values in macOS27 beta
Hi, I have a app group registered in mac os app called gorup.com.company.app and i am saving the key/values in userdefaults to this with suitname. within the mac os app the group userdedaults write/read are working fine. I have a switt cli app with same app group registered in the code signing entitilement for the swit cli app. trying to read the group user default key value registered in mac os app in swift cli app returning no value. this was working fine with macOS 26. Is there some changes have been made in macos 27 in regaard to this?
6
0
786
Jun ’26
Provisioning with Virtualization framework fails with Threading warning
Hi, I saw the mac os 27 new features video https://developer.apple.com/videos/play/wwdc2026/224/?time=64 and was trying Provisioning and i get this warning [Internal] Thread running at User-interactive quality-of-service class waiting on a lower QoS thread running at Default quality-of-service class. Investigate ways to avoid priority inversions at the line try startupOptions.setGuestProvisioning(opts) i have my vm q declared like this let vmQueue = DispatchQueue(label: "VZVirtualMachineQueue", qos: .userInteractive) and i am executing like this self.vmQueue.async { [weak self] in ......... ......... let startupOptions = VZMacOSVirtualMachineStartOptions() try? startupOptions.setGuestProvisioning(opts) vm.start(startupOptions) } and it fails with treading warning and provisioning does not happen. Thanks in advance for the help
6
0
812
Jun ’26
Sandboxed app cannot place File Provider placeholder file URLs on the pasteboard (sandbox error -20)
I'm building a sandboxed macOS app (Developer ID, App Sandbox enabled) with a File Provider extension that exposes on-demand placeholder files under  ~/Library/CloudStorage/<domain>/ . Expected: The app writes the placeholder file URLs to  NSPasteboard.general . The user presses ⌘V in Finder, and Finder fetches the contents on demand via  fetchContents . Observed: • Finder's own copy and paste of the same placeholders works, and  fetchContents  is called at paste time as expected. • When the sandboxed app writes the URLs to the pasteboard,  CFPasteboard  logs:  Sandbox extension creation failed ... (error -20) . The paste does not happen. • Writing  NSPasteboardItem  with  .fileURL  strings instead of  NSURL  objects produces the same error. • Adding  com.apple.security.temporary-exception.files.absolute-path.read-only  for the CloudStorage domain path fixes it. Questions: Is there a supported way for a sandboxed app to put File Provider placeholder URLs on the pasteboard without the temporary-exception entitlement? Is the temporary-exception entitlement acceptable for Mac App Store distribution, or is it only viable for Developer ID builds? Should the app grant itself access another way, for example through a security-scoped bookmark or by using  NSFileProviderManager  APIs?
Replies
3
Boosts
0
Views
197
Activity
23h
Installing a macOS guest onto an external USB disk with Virtualization.framework (sandboxed app)
Hello, We develop a sandboxed Mac App Store app that runs virtual machines with Virtualization.framework on Apple silicon (macOS 27). Users want to install a macOS guest onto an external USB disk and start the VM from it, so they can keep a VM on portable storage or on a disk larger than the Mac's internal drive. What we tried USB passthrough: we attach the disk before the VM starts, with VZUSBPassthroughDeviceConfiguration (from an AAUSBAccessory) on a VZXHCIControllerConfiguration. Linux guests install onto the disk and boot from it without problems. For a macOS guest, VZMacOSInstaller fails to start when the USB disk is the only storage: As we understand it, a macOS VM can only start from its own storage devices, never from a USB device, so even a successful install would not boot. VZDiskBlockDeviceStorageDeviceAttachment: this needs an open file handle to /dev/diskN. That requires admin rights, which a sandboxed app can't obtain, so we can't use it in our App Store app. Questions Is there a supported way to install a macOS guest onto an external USB disk and start the VM from it? Is there a sandbox-compatible way to get a VZDiskBlockDeviceStorageDeviceAttachment for an external disk, for example after user consent, similar to how AccessoryAccess grants USB devices? If neither is possible today, is support for this planned, or is there a recommended alternative? Thank you for any guidance.
Replies
2
Boosts
0
Views
52
Activity
1d
AccessoryAccess in a sandboxed helper: IOUSBHostInterface fails without a temporary-exception entitlement. Is there a supported way?
Hello, We are building USB passthrough for virtual machines on macOS 27 and would appreciate guidance from the AccessoryAccess / IOUSBHost / App Sandbox teams on the supported way to open a USB accessory's interfaces from a sandboxed helper process. WHAT WE ARE BUILDING Our app is a sandboxed macOS app that runs virtual machines. For guests that use Virtualization.framework, USB passthrough already works through VZUSBPassthroughDevice, using the AAUSBAccessory we get from AccessoryAccess. For a second kind of guest we use our own virtual machine monitor, built on Hypervisor.framework. Each VM runs in its own helper process, a nested app bundle in Contents/Helpers that the main app launches with Process. The helper's entitlements are: com.apple.security.app-sandbox = true com.apple.security.inherit = true com.apple.security.hypervisor = true com.apple.vm.networking = true The main app's entitlements include: com.apple.security.app-sandbox = true com.apple.developer.accessory-access.usb = true com.apple.security.device.usb = true (plus hypervisor, networking, files, application groups) The helper emulates an xHCI controller for the guest and forwards the guest's USB transfers to the real device. We use the same AccessoryAccess hand-off the documentation describes for worker processes: The main app registers an AAUSBAccessoryListener with AAUSBAccessoryManager and shows the consent UI. Nothing changed here from the Virtualization.framework path. When the user attaches a device to a VM, the main app calls -[AAUSBAccessory createXPCRepresentation]. We send the bytes of that xpc_data object to the helper over our existing control channel. We use the bytes rather than an XPC connection because the representation contains only data, no Mach ports or file descriptors. The helper rebuilds the accessory with -[AAUSBAccessory initWithXPCRepresentation:] and calls -openWithServiceQueue:completionHandler:. This succeeds and returns an IOUSBHostDevice. In the IORegistry the device then has an AppleUSBHostFrameworkDeviceClient created by the helper. When the guest sends SET_CONFIGURATION, the helper calls -[IOUSBHostDevice configureWithValue:matchInterfaces:NO error:], which succeeds. It then finds the device's IOUSBHostInterface children in the IORegistry and opens each one with -[IOUSBHostInterface initWithIOService:options:queue:error:interestHandler:]. Bulk and interrupt transfers then go through IOUSBHostPipe (copyPipeWithAddress:, enqueueIORequestWithData:...). THE PROBLEM Steps 1-3 work, and so do control requests on the default pipe. The guest enumerates the device and loads its driver. Step 4 fails: every interface fails to open with Failed to create IOUSBHostInterface. (kIOReturnInternalError, 0xe00002c9) With no interfaces open there are no pipes, so the guest's driver fails as soon as it moves data. A USB flash drive reported "This device cannot start (Code 10)", and a USB Ethernet adapter reported "Network cable unplugged". What we found: An unsandboxed command-line tool, run while the helper held the device through AccessoryAccess, opened the same IOUSBHostInterface with no error. The IORegistry then showed an AppleUSBHostFrameworkInterfaceClient under the interface, created by that tool. So the kernel and the accessory state allow the open; the App Sandbox blocks it. /System/Library/Sandbox/Profiles/application.sb contains: (when (entitlement "com.apple.security.device.usb") (allow iokit-open-user-client (iokit-user-client-class "IOUSBDeviceUserClientV2" "IOUSBInterfaceUserClientV3"))) com.apple.security.device.usb (which the app has) therefore covers only the legacy IOUSBLib user clients, not AppleUSBHostFrameworkInterfaceClient, the class IOUSBHostInterface uses. We found no rule for AppleUSBHostFrameworkDeviceClient either. We assume AccessoryAccess authorizes the device client when the accessory is opened, but nothing does the same for the accessory's interfaces. Adding com.apple.security.device.usb to the helper itself doesn't work: the helper is killed at launch (exit status 5). We understand an inherited-sandbox helper may carry only a limited set of entitlements. HOW WE WORKED AROUND IT We added this entitlement to the main app. The helper inherits the app's sandbox, so it gets the exception too: <key>com.apple.security.temporary-exception.iokit-user-client-class</key> <array> <string>AppleUSBHostFrameworkInterfaceClient</string> </array> With it, the helper opens the interfaces and passthrough works: the flash drive mounts in the guest, and the Ethernet adapter gets a DHCP address and passes traffic. We would rather not ship a temporary-exception entitlement, especially since we also distribute through the Mac App Store. QUESTIONS Is opening an accessory's interfaces with IOUSBHostInterface the intended way to do I/O on a device obtained through AccessoryAccess? If so, what is the supported way to authorize AppleUSBHostFrameworkInterfaceClient for a sandboxed process, or a helper inheriting its sandbox, without a temporary exception? Does AccessoryAccess grant access to an accessory's interfaces as well as the IOUSBHostDevice? For example, should a listener registered with interface matching criteria (AAUSBAccessoryMatchingCriteria initWithDeviceMatchingDictionary: interfaceMatchingDictionaries:...) be able to open those interfaces? Or is there an API we missed that returns IOUSBHostInterface or IOUSBHostPipe objects for an opened accessory? Is passing the accessory to a helper as the bytes of -createXPCRepresentation, instead of through an XPC connection, supported? The documentation describes the representation as something sent "via XPC". Our helpers are plain child processes, not XPC services. Should we use the legacy IOUSBLib interface API instead (IOUSBInterfaceInterface through IOCreatePlugInInterfaceForService, client class IOUSBInterfaceUserClientV3, which com.apple.security.device.usb allows)? Is that supported for a device AccessoryAccess has opened for exclusive access, and is it acceptable to mix IOUSBHostDevice from AccessoryAccess with IOUSBLib interface objects for the same device? Would the temporary-exception entitlement above be accepted in App Store review for this case, or should we file a Feedback Assistant request for a dedicated entitlement or an API change? Environment: macOS 27 (Golden Gate), Apple silicon Xcode with the macOS 27 SDK App and helper are signed with the same team; the helper is a nested app bundle in Contents/Helpers using com.apple.security.inherit Tested devices: a USB 3 flash drive (mass storage, Bulk-Only Transport) and a USB 2.5GbE Ethernet adapter (Realtek, vendor 0x0BDA, product 0x8156) We can provide a minimal sample project that reproduces the IOUSBHostInterface failure, plus IORegistry dumps. Thank you for your time.
Replies
8
Boosts
0
Views
494
Activity
5d
How can I set per-window titles in the Window menu for an iPad app running on Apple silicon Mac?
I’m developing a SwiftUI iPad app that runs on an Apple silicon Mac as an iPad app—not as a Mac Catalyst app. The app supports multiple windows, with each Live Screen window associated with a different virtual machine. In the macOS Window menu, all child windows appear as “VirtualProg” rather than showing their content or VM name. The Live Screen window is created from a data-driven  WindowGroup , roughly like this: WindowGroup(id: "vm-screen", for: String.self) { $vmName in VMScreenWindow(vmName: vmName) .navigationTitle(vmName.map { "Live ($0)" } ?? "Live Screen") } I’ve tried setting the title with  .navigationTitle  both on the  WindowGroup  content and inside the window’s  NavigationStack . I also tried setting  windowScene.title  on the specific scene obtained from  view.window?.windowScene  after the view controller appeared. Neither changed the Window-menu entries. Is there a supported way to set a per-window title for the macOS Window menu when running an iPad app on Mac? Does  UIScene.title  affect that menu, or only the window title bar and app switcher? Is this a limitation of the iPad-app-on-Mac runtime, or is there a recommended SwiftUI/UIKit lifecycle hook for this? I’m looking for a public API solution rather than private AppKit/window introspection.
Replies
4
Boosts
1
Views
810
Activity
1w
com.apple.vm.networking for helper binary
Hi everyone & DTS engineers, I am developing a macOS application that uses Apple's Virtualization framework and vmnet APIs. In my main application bundle, I have requested and received approval for the restricted entitlement com.apple.vm.networking. The main app works as expected with bridging/vmnet features. Now, I have embedded a command-line helper binary inside the app bundle (Contents/MacOS/). The helper is configured as follows: Set up with com.apple.security.app-sandbox = true Inherits App Sandbox rules (com.apple.security.inherit = true) Signed with com.apple.vm.networking = true in its entitlements file. However, when launching or invoking networking features from this helper binary, it fails to execute the expected vmnet functions / gets blocked at runtime. My questions for DTS / Apple Engineers: Since com.apple.vm.networking is a restricted entitlement tied to a specific App ID / Provisioning Profile, does an embedded CLI helper tool with its own Bundle ID need to be explicitly registered and granted this entitlement separately in the Developer Portal? If the helper uses com.apple.security.inherit, does AMFI still strictly evaluate the helper's own provisioning profile signature against com.apple.vm.networking independently of the main app bundle? What is the recommended architectural pattern for vmnet access when using helper tools—should network creation stay strictly in the main app process and communicate via XPC, or should the helper tool be granted its own matching profile and entitlement? Thanks in advance for any insight!
Replies
11
Boosts
0
Views
489
Activity
1w
Hypervisor.framework: guest RAM counted twice in phys_footprint after both host and guest write a page
Hello, I'm building a virtualization app on Hypervisor.framework (Apple silicon). Guest RAM is anonymous memory mapped with hv_vm_map. Activity Monitor and task_info(TASK_VM_INFO).phys_footprint show the VM process using much more memory than the guest is assigned. For example, a 6 GB Windows ARM64 guest shows about 8.6 GB. Here's what I've found: Pages written only from the host count once. Pages written only by the guest count once. A page written by both the host and the guest counts twice, even though it is the same physical page. The host reads back the guest's writes, so there's no second copy. In a real VM this happens all the time. The VM process writes into guest RAM for firmware loading, disk reads, virtio buffers and so on, and the guest writes the same pages. So the reported footprint keeps growing past the guest's RAM size. Minimal reproducer (needs the com.apple.security.hypervisor entitlement): // clang -O1 -o hvfootprint hvfootprint.c -framework Hypervisor // codesign -s - --entitlements hv.entitlements -f hvfootprint #include <Hypervisor/Hypervisor.h> #include <mach/mach.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #define MB (1024ull * 1024) #define GPA 0x40000000ull #define SIZE (2048 * MB) #define PAGE 16384 static uint64_t phys_footprint_mb(void) { task_vm_info_data_t info; mach_msg_type_number_t count = TASK_VM_INFO_COUNT; task_info(mach_task_self(), TASK_VM_INFO, (task_info_t)&info, &count); return info.phys_footprint / MB; } // Guest (EL1, MMU off): x0 = start GPA, x1 = value, x2 = page count. // Stores x1 to each 16 KB page, then exits with HVC. static const uint32_t guest_code[] = { 0xf9000001, // str x1, [x0] 0x91401000, // add x0, x0, #0x4000 0xf1000442, // subs x2, x2, #1 0x54ffffa1, // b.ne 0b 0xd4000002, // hvc #0 }; static void guest_write_all(hv_vcpu_t vcpu, uint64_t value) { hv_vcpu_set_reg(vcpu, HV_REG_PC, GPA); hv_vcpu_set_reg(vcpu, HV_REG_CPSR, 0x3c5); hv_vcpu_set_reg(vcpu, HV_REG_X0, GPA + PAGE); hv_vcpu_set_reg(vcpu, HV_REG_X1, value); hv_vcpu_set_reg(vcpu, HV_REG_X2, SIZE / PAGE - 1); hv_vcpu_run(vcpu); } int main(void) { uint8_t *ram = mmap(NULL, SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); hv_vm_create(NULL); hv_vm_map(ram, GPA, SIZE, HV_MEMORY_READ | HV_MEMORY_WRITE | HV_MEMORY_EXEC); memcpy(ram, guest_code, sizeof(guest_code)); hv_vcpu_t vcpu; hv_vcpu_exit_t *exit_info; hv_vcpu_create(&vcpu, &exit_info, NULL); printf("start: phys_footprint %5llu MB\n", phys_footprint_mb()); for (uint64_t off = PAGE; off < SIZE; off += PAGE) // host writes every page ram[off] = 1; printf("host wrote 2 GB: phys_footprint %5llu MB\n", phys_footprint_mb()); guest_write_all(vcpu, 0x55); // guest writes the same pages printf("guest wrote the same 2 GB: phys_footprint %5llu MB\n", phys_footprint_mb()); printf("host sees guest data (same pages): %s\n", ram[PAGE] == 0x55 ? "yes" : "no"); guest_write_all(vcpu, 0x66); // and again printf("guest wrote the same 2 GB again: phys_footprint %5llu MB\n", phys_footprint_mb()); return 0; } Output (macOS 27.0.1, build 26A434, Apple M5): start: phys_footprint 2 MB host wrote 2 GB: phys_footprint 2050 MB guest wrote the same 2 GB: phys_footprint 4099 MB host sees guest data (same pages): yes guest wrote the same 2 GB again: phys_footprint 4099 MB 2 GB of shared guest RAM is reported as 4 GB. Other observations The result is the same whether guest RAM comes from mmap(MAP_PRIVATE | MAP_ANON), mmap(MAP_SHARED | MAP_ANON), mach_vm_allocate, or a named memory entry (mach_make_memory_entry_64 with MAP_MEM_NAMED_CREATE) mapped twice, with one view passed to hv_vm_map and the other used by the host. footprint region totals ("Footprint:" / Dirty) count only pages the host touched. When only the guest wrote 2 GB, the regions showed about 3 MB while phys_footprint showed 2,051 MB. So neither number shows real usage once both sides touch memory. System-wide anonymous memory (host_statistics64, internal_page_count + compressor_page_count) does not grow when the guest writes pages the host already wrote. That suggests this is accounting only, not a second physical copy. Parallels describes the same symptom for its VMs (https://kb.parallels.com/en/128437). Questions Is this double accounting expected for memory mapped with hv_vm_map, or is it a bug? If it's a bug, I'll file it in Feedback Assistant with this reproducer. Is there a supported way to allocate or map guest RAM so each physical page is charged to the process once? For example, a ledger tag, memory-entry ownership, or an hv_vm_map / hv_vm_allocate option. Is phys_footprint the right input for memory-pressure decisions (jetsam) for a VM process? Could the double count make such a process look larger than it is to the system? What is the recommended way to report a VM process's real memory use to users? Thank you.
Replies
2
Boosts
0
Views
359
Activity
2w
VZVirtualMachineView.automaticallyReconfiguresDisplay does not work for Golden Gate
I am using Virtualization framework for running Golden Gate VM in swift ui window with VZVirtualMachineView. i have set the automaticallyReconfiguresDisplay to true. but when i resize the window the resolution of Golden Gate does not change automatically to fit the window. This works fine for Tahoe. Golden Gate is not respecting the automaticallyReconfiguresDisplay. Any help in fixing this bug would be very helpful to me. Thanks in advance
Replies
6
Boosts
0
Views
810
Activity
3w
AAUSBAccessoryManager does not fire didconnect
Hi, I am trying to use AAUSBAccessoryManager with mac os 27 to connect host usb device to guest vm. here is my code // // USBPassthroughManager.swift // VirtualProg import AccessoryAccess import Foundation import IOKit @available(macOS 27.0, *) class USBPassthroughManager: NSObject, ObservableObject, AAUSBAccessoryListener { static let shared = USBPassthroughManager() @Published var availableDevices: [AAUSBAccessory] = [] func startListening() async { do { let existing = try await AAUSBAccessoryManager.shared .registerListener(self, matchingCriteria: []) await MainActor.run { self.availableDevices = existing } } catch { LogManager.shared.log(vmName: AppConstants.logGeneral, type: .error, message: "USB passthrough listener failed: \(error.localizedDescription)") } } func usbAccessoryDidConnect(_ usbAccessory: AAUSBAccessory) { DispatchQueue.main.async { guard !self.availableDevices.contains(where: { $0.registryID == usbAccessory.registryID }) else { return } self.availableDevices.append(usbAccessory) print(self.displayName(for: usbAccessory)) } } The usb icon in status bar menu is displayed and i can select the the usb device to connect to my app. the usb device is connected to my app. it is shown in the status bar. but usbAccessoryDidConnect is not firing. i have the entitlement com.apple.developer.accessory-access.usb in the capabilities. i get this in the xcode console start failed ((iokit/common) not permitted) for plugin for .......... and also disconnect is also not firing. Not sure what i am doing wrong. How can i determine the name of the USB Device from AAUSBAccessory. Any help would be appreciated. Thanks
Replies
8
Boosts
1
Views
837
Activity
Sep ’26
Programmatic IP Discovery for VZVirtualMachine in an App Store Sandbox
Hi everyone, I am developing a macOS virtualization manager (VirtualProg) using the Virtualization.framework. The application is distributed via the Mac App Store, so it operates strictly within the App Store Sandbox. I am looking for a reliable, programmatic way to discover the IP address assigned to a guest (both macOS and Linux). Is there a recommended "Sandbox-safe" API or pattern within the Virtualization framework—or a lower-level networking entitlement—that allows a host application to retrieve the guest's assigned IP address? Ideally, I am looking for a solution that does not require the user to manually install a non-sandboxed helper tool. Thanks in advance for any insights or guidance!
Replies
33
Boosts
0
Views
3.4k
Activity
Jun ’26
app groups user defaults are not returning values in macOS27 beta
Hi, I have a app group registered in mac os app called gorup.com.company.app and i am saving the key/values in userdefaults to this with suitname. within the mac os app the group userdedaults write/read are working fine. I have a switt cli app with same app group registered in the code signing entitilement for the swit cli app. trying to read the group user default key value registered in mac os app in swift cli app returning no value. this was working fine with macOS 26. Is there some changes have been made in macos 27 in regaard to this?
Replies
6
Boosts
0
Views
786
Activity
Jun ’26
Provisioning with Virtualization framework fails with Threading warning
Hi, I saw the mac os 27 new features video https://developer.apple.com/videos/play/wwdc2026/224/?time=64 and was trying Provisioning and i get this warning [Internal] Thread running at User-interactive quality-of-service class waiting on a lower QoS thread running at Default quality-of-service class. Investigate ways to avoid priority inversions at the line try startupOptions.setGuestProvisioning(opts) i have my vm q declared like this let vmQueue = DispatchQueue(label: "VZVirtualMachineQueue", qos: .userInteractive) and i am executing like this self.vmQueue.async { [weak self] in ......... ......... let startupOptions = VZMacOSVirtualMachineStartOptions() try? startupOptions.setGuestProvisioning(opts) vm.start(startupOptions) } and it fails with treading warning and provisioning does not happen. Thanks in advance for the help
Replies
6
Boosts
0
Views
812
Activity
Jun ’26