Skip to content

vm(apple): implement USB passthrough for Apple Virtualization#7632

Merged
osy merged 1 commit intomainfrom
feature/avf-usb-capture
Feb 27, 2026
Merged

vm(apple): implement USB passthrough for Apple Virtualization#7632
osy merged 1 commit intomainfrom
feature/avf-usb-capture

Conversation

@osy
Copy link
Contributor

@osy osy commented Feb 26, 2026

This change implements USB device passthrough for macOS 15+ using the Virtualization framework private APIs.

Changes include:

  • UTMIOUSBHostManager: Uses IOKit to dynamically manage connected USB devices. Instead of relying on private framework headers, it uses Objective-C reflection to safely instantiate _VZIOUSBHostPassthroughDeviceConfiguration and _VZIOUSBHostPassthroughDevice, and configures delegates for VZUSBController.

  • UTMIOUSBHostDevice: Represents an IOKit USB device, conforming to NSSecureCoding and NSCopying. It safely reads properties such as location ID and port directly from the IORegistry.

  • UTMAppleVirtualMachine: Now initializes UTMIOUSBHostManager and restores captured USB devices asynchronously before VM startup. State is archived directly into the registry.

  • VMDisplayAppleWindowController: Added a new USB menu populated with current devices to allow interactively connecting and disconnecting USB devices on the fly.

  • UTMRegistryEntry: Extended to support archiving and unarchiving of connected USB devices.

  • I have read the AI Contribution Guidelines and can attest that I have followed each item to the best of my ability.

This change implements USB device passthrough for macOS 15+ using the
Virtualization framework private APIs.

Changes include:
- `UTMIOUSBHostManager`: Uses IOKit to dynamically manage connected USB devices.
  Instead of relying on private framework headers, it uses Objective-C reflection
  to safely instantiate `_VZIOUSBHostPassthroughDeviceConfiguration` and
  `_VZIOUSBHostPassthroughDevice`, and configures delegates for `VZUSBController`.
- `UTMIOUSBHostDevice`: Represents an IOKit USB device, conforming to `NSSecureCoding`
  and `NSCopying`. It safely reads properties such as location ID and port directly
  from the IORegistry.
- `UTMAppleVirtualMachine`: Now initializes `UTMIOUSBHostManager` and restores captured
  USB devices asynchronously before VM startup. State is archived directly into the registry.
- `VMDisplayAppleWindowController`: Added a new USB menu populated with current devices
  to allow interactively connecting and disconnecting USB devices on the fly.
- `UTMRegistryEntry`: Extended to support archiving and unarchiving of connected USB devices.

Co-authored-by: Gemini <gemini@google.com>
@osy osy added this to the v5.0 milestone Feb 26, 2026
@osy osy linked an issue Feb 26, 2026 that may be closed by this pull request
@wjk
Copy link

wjk commented Feb 26, 2026

using the Virtualization framework private APIs

How do you expect this to pass Mac App Store review?

@osy
Copy link
Contributor Author

osy commented Feb 26, 2026

@wjk Well we're not doing anything different from what Parallels Desktop does. https://apps.apple.com/us/app/parallels-desktop/id1085114709

#3778 (comment)

All I did was tell Gemini to look at what Parallels does and replicate it.

@wjk
Copy link

wjk commented Feb 26, 2026

😕 I suppose…

Parallels is a big company, meaning that Apple may be more inclined to look the other way concerning private APIs with their app as compared to UTM. And their private-API scanner must not be very sophisticated if it allows people to bypass it this easily.

On the other hand, you have had private CoreGraphics APIs referenced in the bridging header since 2021 per the blame, and the App Store lists versions back to 2022. I guess that’s OK with them? 😜

@osy
Copy link
Contributor Author

osy commented Feb 26, 2026

We expect all apps to be treated the same way as Apple and that all apps follow the same rules. If Apple has an issue with the use of these APIs, we will happily revert this change provided the same is asked of Parallels.

@osy
Copy link
Contributor Author

osy commented Feb 27, 2026

So it is with a heavy heart that I have to abandon this PR (at least until Apple makes the APIs public). The underlying assumption was that Parallels used the private APIs so we can too right? Well, after extensive research, I can say that USB capture does not work in macOS guests in the App Store version.

In order to get it working, it's not just a matter of calling the private APIs (which is quite easy to do as seen by the PR). You also need an entitlement com.apple.security.temporary-exception.iokit-user-client-class that Apple must manually review and grant (which I doubt they will). I did not commit the change where I added this entitlement because I had assumed that Parallels had a way of doing it without that entitlement but after a long and windy road, I've come to the conclusion that nobody at Parallels Desktop tests their products either (although TBF we are trying to build a testing infrastructure and we don't have hundreds of millions of dollars).

So I am going to leave this PR in draft for now. Until either 1) Apple makes this API public, or 2) we decide to maintain a non-sandboxed version of UTM macOS which is not difficult but comes with huge operational burden.

@osy osy removed this from the v5.0 milestone Feb 27, 2026
@osy osy marked this pull request as draft February 27, 2026 20:10
@osy osy merged commit 9d34c59 into main Feb 27, 2026
91 checks passed
@osy
Copy link
Contributor Author

osy commented Feb 27, 2026

Messed up because I forgot my local main branch had the commit in place. I reverted the commit and opened a new PR #7635 to track this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add USB sharing option to macOS guest (from macOS host)

2 participants