DriverKit issue with TestFlight

Hi,

We’re developing a DriverKit extension for iPadOS. In local Debug and Release builds, everything works as expected, but the same build uploaded to TestFlight fails at IOServiceOpen with the following errors:

-536870212 (0xE00002EC) kIOReturnUnsupported

-536870201 (0xE00002F7) kIOReturnNotPermitted

What we’ve verified so far

  1. App entitlements

We checked our main app entitlements file, and it has the correct capabilities for the driverkit communication

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.driverkit.communicates-with-drivers</key>
	<true/>
	<key>com.apple.developer.driverkit.userclient-access</key>
	<array>
		<string>abc.def.ABCDriver</string>
	</array>
	<key>com.apple.developer.system-extension.install</key>
	<true/>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.device.usb</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
</dict>
</plist>
  1. we also checked the Provisioning profile (as shown on the portal) and the “Enabled Capabilities” seems to have the correct DriverKit Capabilities enabled.
Enabled Capabilities

Access Wi-Fi Information, DriverKit, DriverKit (development), DriverKit Communicates with Drivers, DriverKit USB Transport (development), DriverKit USB Transport - VendorID, DriverKit UserClient Access, iCloud, In-App Purchase, Sign In with Apple, System Extension
  1. When we download and inspect the provisioning profile as plain text, we notice that some expected DriverKit entitlements appear to be missing from the <Entitlements> section.
<key>Entitlements</key>
<dict>
    <key>beta-reports-active</key>
    <true/>
          
          <key>com.apple.developer.networking.wifi-info</key>
    <true/>
          
          <key>com.apple.developer.driverkit</key>
    <true/>
          
          <key>com.apple.developer.driverkit.communicates-with-drivers</key>
    <true/>
          
          <key>application-identifier</key>
    <string>ABC123456.abc.def</string>
          
          <key>keychain-access-groups</key>
    <array>
          <string>ABC123456.*</string>
          <string>com.apple.token</string>
    </array>
          
          <key>get-task-allow</key>
    <false/>
          
          <key>com.apple.developer.team-identifier</key>
    <string>ABC123456</string>
          
          <key>com.apple.developer.ubiquity-kvstore-identifier</key>
    <string>ABC123456.*</string>
          
          <key>com.apple.developer.icloud-services</key>
    <string>*</string>
          
          <key>com.apple.developer.icloud-container-identifiers</key>
    <array></array>
          
          <key>com.apple.developer.icloud-container-development-container-identifiers</key>
    <array></array>
          
          <key>com.apple.developer.ubiquity-container-identifiers</key>
    <array></array>
          
          <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
                <dict>
          
          <key>idVendor</key>
    <integer>1234</integer>
                </dict>
    </array>
          
          <key>com.apple.developer.applesignin</key>
    <array>
          <string>Default</string>
    </array>

</dict>

We have a couple of questions:

  1. Could the missing com.apple.developer.driverkit.userclient-access entitlement in the provisioning profile alone explain the kIOReturnUnsupported / kIOReturnNotPermitted failures from IOServiceOpen?

  2. Why do some DriverKit capabilities appear in the Apple Developer portal UI but vanish from the actual profile we download? Is there an extra step we’re overlooking when regenerating profiles after toggling those capabilities?

Thanks

Answered by DTS Engineer in 848999022

Below are the Info.plist, entitlements, and App Store profiles for our driver and client app.

So, as a quick side comment, when looking into an issue like this, it's critical to look at the actual Info.plist file, not just the Xcode project settings. I happened to have been sent your DEXT by one of our evangelists, but without the actual data, I probably wouldn't have thought of this.

In any case, here is the CFBundleVersion of your development DEXT:

CFBundleVersion = 1

And here is your TestFlight version:

CFBundleVersion = 3433099.287482533

You can read the full details here, but that second version simply will not work in a DEXT/KEXT.

I suspect that's the problem here, but covering a few odds and ends:

  1. Our driver’s Info.plist specifies both idVendor and idProduct, but our entitlements and provisioning profiles currently include only the idVendor. Do we need to request approval or entitlement inclusion for the idProduct as well?

No. There are actually two mechanisms at work here that operate independently.

  1. Your codesign configuration determines what device you’re "eligible" to be matched with. In your case, that means your DEXT is a candidate to be loaded for any USB device with an idVendor = 1234. This is what controls whether or not the kernel "sees" your DEXT for any given device.

  2. The contents of your IOKitPersonalities are what the kernel ACTUALLY uses for matching. In your case, that means that this particular DEXT will match with a device that has this configuration:

bConfigurationValue = 1
bInterfaceNumber = 0
idProduct = 5678
idVendor = 1234

It's actually fairly normal for #1 to be significantly broader than #2, as that's how vendors ship different drivers for different hardware without needing a different entitlement set for EVERY single device they ship.

  1. We’ve noticed that our development provisioning profiles use wildcard matching for idVendor:

This is normal, as this is how the development only variants allow matching to "any" hardware.

Is there a way to update our development profiles to match the App Store versions?

Theoretically, yes. In theory, you could generate manual provisioning profiles for the DEXT and then switch to "manual" codesigning in Xcode. However, I would strongly recommend against doing so. When it comes to DEXT signing, there are basically two cases in Xcode 16:

  1. Your team configuration is simple enough that automatic code-signing actually works.

  2. Your team configuration is complex enough that distribution signing breaks, forcing you to manually sign distribution builds.

In the first case, you should enjoy that fact and ignore this issue. In the second case, you should celebrate the fact that at least you don't have to deal with development builds... and ignore this issue.

One thing to understand here is what "wrongly" signed would actually mean. There are basically two cases:

  1. Your entitlement is misconfigured in a way that makes your DEXT nonfunctional. For example, if your entitlement is configured as "idVendor=4321" but your hardware is "idVendor=1234", then that DEXT is incapable of EVER actually running against hardware. This is a case you might want to check for, but it's not something that will really "break" once it's been properly configured on our side.

  2. "Something" about your configuration is "wrong" that makes your app signing configuration incapable of running.

My experience has been that, at least for DEXT, all signing errors seem to happen at build time, NOT install or run time. That is, once you get a DEXT signed it won't fail because of codesigning. That's definitely the case here, as that KEXT version check is basically as old as the system is.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

In addition to the main app's entitlements and provisioning profile described above, here are the entitlements and provisioning profile details for our DriverKit extension:

Driver Entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>com.apple.developer.driverkit</key>
	<true/>
	<key>com.apple.developer.driverkit.transport.usb</key>
	<array>
		<dict/>
	</array>
	<key>com.apple.security.app-sandbox</key>
	<true/>
</dict>
</plist>

Entitlements section in the Driver's Provisioning Profile


    <key>Entitlements</key>
    <dict>
        <key>beta-reports-active</key>
        <true/>
                
                <key>com.apple.developer.driverkit</key>
        <true/>
                
                <key>application-identifier</key>
        <string>ABC123456.abc.def.ABCDriver</string>
                
                <key>com.apple.developer.driverkit.transport.usb</key>
        <array>
                        <dict>
                
                <key>idVendor</key>
        <integer>1234</integer>
                        </dict>
        </array>
                
                <key>com.apple.developer.driverkit.allow-third-party-userclients</key>
        <true/>
                
                <key>keychain-access-groups</key>
        <array>
                <string>ABC123456.*</string>
                <string>com.apple.token</string>
        </array>
                
                <key>get-task-allow</key>
        <false/>
                
                <key>com.apple.developer.team-identifier</key>
        <string>ABC123456</string>

    </dict>

Please ignore the IOServiceOpen errors above.

We've observed that after uploading our build to TestFlight, the driver is no longer being detected. Specifically, we’re unable to find the matching driver service, and the expected "Service name: ..." log does not appear—even after connecting the hardware and enabling the driver in the iOS App settings.

The same code works reliably in local (non-TestFlight) builds, where we're able to successfully detect the driver and establish a connection. Here's the relevant snippet for reference:

func isDriverMatched() -> Bool {
    var bDriverMatched = false
    var serviceMatchItr: io_iterator_t = 0
    
    if #available(iOS 15.0, *) {
        guard let matchingDict = IOServiceMatching("IOUserService") else {
            Log.e(with: "TAG", with: "Failed to create matching dictionary")
            return false
        }
        
        let key = "IOUserServerName" as CFString
        let serverName = "abc.def.ABCDriver" as CFString
        CFDictionarySetValue(matchingDict, Unmanaged.passUnretained(key).toOpaque(), Unmanaged.passUnretained(serverName).toOpaque())
        
        let serviceMatchedError = IOServiceGetMatchingServices(kIOMainPortDefault, matchingDict, &serviceMatchItr)
        guard serviceMatchedError == kIOReturnSuccess else {
            PCOPiLog.e(with: "TAG", with: "Failed to find matching service")
            IOObjectRelease(serviceMatchItr)
            return false
        }
        
        var service: io_object_t
        repeat {
            service = IOIteratorNext(serviceMatchItr)
            if service != 0 {
                
                var serviceNameCString = [CChar](repeating: 0, count: 128)
                var serviceName = "Service name: <Unknown>"
                if IORegistryEntryGetName(service, &serviceNameCString) == KERN_SUCCESS {
                    serviceName = String(cString: serviceNameCString)
                    PCOPiLog.i(with: "TAG", with: "Service name: \(serviceName)")
                } else {
                    PCOPiLog.i(with: "TAG", with: "Service name: <Unknown>")
                }
                //
                ...........................                    

            }
        } while service != 0
        
        if !bDriverMatched {
            PCOPiLog.e(with: "TAG", with: "No matching driver service found or not responsive.")
        }
    } else {
        return false
    }
    
    IOObjectRelease(serviceMatchItr)
    return bDriverMatched
}

We investigated further by unzipping both the TestFlight .ipa and the archive from Xcode. The dext is present in both builds, but the .dext inside the .ipa is noticeably smaller (~150 KB) compared to the one in the archive (~350 KB).

We also extracted the entitlements from the signed app bundle in the .ipa. Here's what was included:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>application-identifier</key>
    <string>ABC123456.abc.def</string>
    <key>beta-reports-active</key>
    <true/>
    <key>com.apple.developer.driverkit.communicates-with-drivers</key>
    <true/>
    <key>com.apple.developer.team-identifier</key>
    <string>ABC123456</string>
    <key>get-task-allow</key>
    <false/>
  </dict>
</plist>

This set is missing some key entitlements compared to our app's original entitlements file. It’s unclear why the packaging or signing process is dropping these during TestFlight submission.

We also checked the entitlements embedded in the .dext itself (inside the .ipa)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>application-identifier</key>
    <string>ABC123456.abc.def.ABCDriver</string>
    <key>beta-reports-active</key>
    <true/>
    <key>com.apple.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
      <dict/>
    </array>
    <key>com.apple.developer.team-identifier</key>
    <string>ABC123456</string>
    <key>get-task-allow</key>
    <false/>
  </dict>
</plist>

Question:

Could the missing entitlements in the main app bundle from the .ipa—prevent the system from detecting or loading the driver at runtime? Also, could the smaller .dext size in the .ipa suggest it is being stripped or excluded in some way?

We would appreciate any insights or recommendations.

Thanks!

  1. Could the missing com.apple.developer.driverkit.userclient-access entitlement in the provisioning profile alone explain the kIOReturnUnsupported / kIOReturnNotPermitted failures from IOServiceOpen?

No, but iPadOS apps should not include "com.apple.developer.driverkit.userclient-access". Note that your construction of that entitlement is also invalid (it's a list of bundle IDs and requires approval to use), though that could be an accident of your cut/paste. See this forum post for the details of the user client entitlements.

  1. Why do some DriverKit capabilities appear in the Apple Developer portal UI but vanish from the actual profile we download? Is there an extra step we’re overlooking when regenerating profiles after toggling those capabilities?

The main issue is that Development entitlement variants are ONLY included in developer profiles and not in any other context. Note that this does mean that a misconfigured DEXT can work in development but not in production because the development entitlements allow very broad matching.

In addition to the main app's entitlements and provisioning profile described above, here are the entitlements and provisioning profile details for our DriverKit extension:

Assuming the contents you've posted are accurate, then this mismatch is the problem:

<key>com.apple.developer.driverkit.transport.usb</key>
<array>
	<dict/>
</array>

<key>com.apple.developer.driverkit.transport.usb</key>
<array>
	<dict>
		<key>idVendor</key>
		<integer>1234</integer>
	</dict>
</array>

Those dictionaries must match in order for your DEXT to load.

HOWEVER....

We've observed that after uploading our build to TestFlight, the driver is no longer being detected. Specifically, we’re unable to find the matching driver service, and the expected "Service name: ..." log does not appear—even after connecting the hardware and enabling the driver in the iOS App settings.

Details matter here. The system has detected your DEXT; otherwise, you wouldn't have anything to enable. Similarly, most code sign issues would either prevent app installation or disable the "Enable DEXT" interface. The fact you're able to enable your DEXT at all implies that the signing is at least coherent, if not correct.

The next step here is to debug matching and loading, which basically means capturing the system log and going through it to determine exactly what happened when your device was attached.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

Thanks for the response.

No, but iPadOS apps should not include "com.apple.developer.driverkit.userclient-access". Note that your construction of that entitlement is also invalid (it's a list of bundle IDs and requires approval to use),

We realized this was for MacOS only and since our app is for iOS, we plan to remove this. The actual bundleId was approved and we just use a censored bundle ID here

Assuming the contents you've posted are accurate, then this mismatch is the problem:

Those dictionaries must match in order for your DEXT to load.

Yes, we also noticed the missing idVendor in our driver entitlement and updated it to match the provisioning profile. However, the issue still persists—our DriverKit is realized but does not start in the TestFlight build.

Local Build (works): After enabling the driver and connecting the hardware, the system logs show the driver is both realized and started successfully.

TestFlight Build (broken): On the same hardware and sequence, the system only logs the realization of the driver, but none of the usual logs from init() or Start() appear.

driverkitd	Realize dext ABC123456.abc.def.ABCDriver

//Missing logs below showing our driver is initialized and started in TestFlight build

kernel Driver ABC123456.abc.def.ABCDriver has crashed 0 time(s)
kernel DK: ABCDriver-0x100001b68 waiting for server ABC123456.abc.def.ABCDriver-100001b68
driverkitd Figuring out dext launch context: ABC123456.abc.def.ABCDriver
............
driverkitd Launching dext ABC123456.abc.def.ABCDriver ABC123456.abc.def.ABCDriver 0x100001b68 ....
driverkitd Launching driver extension via running board: Dext ABC123456.abc.def.ABCDriver v1 .....
.......
kernel ABCDriver - init()
kernel ABCDriver - Start()


Below are the info plist, entitlements and app store profiles for our driver and client app.

Driver info.plist

<plist version="1.0">
<dict>
	<key>CFBundleDisplayName</key>
	<string>ABDC Driver</string>
	<key>OSBundleUsageDescription</key>
	<string>abdcef</string>
	<key>IOKitPersonalities</key>
	<dict>
		<key>ABCDriver</key>
		<dict>
			<key>CFBundleIdentifier</key>
			<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
			<key>CFBundleIdentifierKernel</key>
			<string>com.apple.kpi.iokit</string>
			<key>CFBundleName</key>
			<string>$(PRODUCT_NAME)</string>
			<key>IOClass</key>
			<string>IOUserService</string>
			<key>IOMatchCategory</key>
			<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
			<key>IOProviderClass</key>
			<string>IOUSBHostDevice</string>
			<key>IOResourceMatch</key>
			<string>IOKit</string>
			<key>IOUserClass</key>
			<string>ABCDriver</string>
			<key>IOUserServerName</key>
			<string>abc.def.ABCDriver</string>
			<key>ABCDriverUserClientProperties</key>
			<dict>
				<key>IOClass</key>
				<string>IOUserUserClient</string>
				<key>IOUserClass</key>
				<string>ABCDriverClient</string>
			</dict>
			<key>bConfigurationValue</key>
			<integer>1</integer>
			<key>bInterfaceNumber</key>
			<integer>0</integer>
			<key>idProduct</key>
			<integer>5678</integer>
			<key>idVendor</key>
			<integer>1234</integer>
		</dict>
	</dict>
</dict>
</plist>

Driver entitlements

<plist version="1.0">
<dict>
	<key>com.apple.developer.driverkit</key>
	<true/>
<key>com.apple.developer.driverkit.transport.usb</key>
	<array>
		<dict>
			<key>idVendor</key>
			<integer>1234</integer>
		</dict>
	</array>
	<key>com.apple.security.app-sandbox</key>
	<true/>
</dict>
</plist>

Driver app store profile

<key>Entitlements</key>
	<dict>
		<key>beta-reports-active</key>
		<true/>
				
				<key>com.apple.developer.driverkit</key>
		<true/>
				
				<key>application-identifier</key>
		<string>ABC123456.abc.def.ABCDriver</string>
				
				<key>com.apple.developer.driverkit.transport.usb</key>
		<array>
						<dict>
				
				<key>idVendor</key>
		<integer>1234</integer>
						</dict>
		</array>
				
				<key>keychain-access-groups</key>
		<array>
				<string>ABC123456.*</string>
				<string>com.apple.token</string>
		</array>
				
				<key>get-task-allow</key>
		<false/>
				
				<key>com.apple.developer.team-identifier</key>
		<string>ABC123456</string>

	</dict>

Client app entitlements

<plist version="1.0">
<dict>
	<key>com.apple.developer.driverkit.communicates-with-drivers</key>
	<true/>
	<key>com.apple.developer.driverkit.userclient-access</key>
	<array>
		<string>abc.def.ABCDriver</string>
	</array>
	<key>com.apple.developer.system-extension.install</key>
	<true/>
	<key>com.apple.security.app-sandbox</key>
	<true/>
	<key>com.apple.security.device.usb</key>
	<true/>
	<key>com.apple.security.files.user-selected.read-write</key>
	<true/>
	<key>com.apple.developer.driverkit</key>
	<true/>
<key>com.apple.developer.driverkit.transport.usb</key>
	<array>
		<dict>
			<key>idVendor</key>
			<integer>1234</integer>
		</dict>
	</array>
</dict>
</plist>

Client app store profile

<key>Entitlements</key>
	<dict>
		<key>beta-reports-active</key>
		<true/>
				
				<key>com.apple.developer.networking.wifi-info</key>
		<true/>
				
				<key>com.apple.developer.driverkit</key>
		<true/>
				
				<key>com.apple.developer.driverkit.communicates-with-drivers</key>
		<true/>
				
				<key>application-identifier</key>
		<string>ABC123456.abc.def</string>
				
				<key>keychain-access-groups</key>
		<array>
				<string>ABC123456.*</string>
				<string>com.apple.token</string>
		</array>
				
				<key>get-task-allow</key>
		<false/>
				
				<key>com.apple.developer.team-identifier</key>
		<string>ABC123456</string>
				
				<key>com.apple.developer.ubiquity-kvstore-identifier</key>
		<string>ABC123456.*</string>
				
				<key>com.apple.developer.icloud-services</key>
		<string>*</string>
				
				<key>com.apple.developer.icloud-container-identifiers</key>
		<array></array>
				
				<key>com.apple.developer.icloud-container-development-container-identifiers</key>
		<array></array>
				
				<key>com.apple.developer.ubiquity-container-identifiers</key>
		<array></array>
				
				<key>com.apple.developer.driverkit.transport.usb</key>
		<array>
						<dict>
				
				<key>idVendor</key>
		<integer>1234</integer>
						</dict>
		</array>
				
				<key>com.apple.developer.applesignin</key>
		<array>
				<string>Default</string>
		</array>

	</dict>

Please let us know if anything in our configuration appears to be missing or incorrect. We also have a couple of questions:

  1. Our driver’s Info.plist specifies both idVendor and idProduct, but our entitlements and provisioning profiles currently include only the idVendor. Do we need to request approval or entitlement inclusion for the idProduct as well?

  2. We’ve noticed that our development provisioning profiles use wildcard matching for idVendor:

<key>idVendor</key>
<string>*</string>

whereas the App Store profiles use an explicit integer value:

<key>idVendor</key>
<integer>1234</integer>

Is there a way to update our development profiles to match the App Store versions?

Thanks!

I extracted and inspected the entitlements from both the built app and the embedded DriverKit extension (dext) in the .ipa. Below are the details:

App Entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>application-identifier</key>
    <string>ABC123456.abc.def</string>
    <key>beta-reports-active</key>
    <true/>
    <key>com.apple.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.communicates-with-drivers</key>
    <true/>  <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
      <dict>
        <key>idVendor</key>
        <integer>1234</integer>
      </dict>
    </array>
    <key>com.apple.developer.team-identifier</key>
    <string>ABC123456</string>
    <key>get-task-allow</key>
    <false/>
  </dict>
</plist>

Driver Extension (dext) Entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
  <dict>
    <key>application-identifier</key>
    <string>ABC123456.abc.def.ABCDriver</string>
    <key>beta-reports-active</key>
    <true/>
    <key>com.apple.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
      <dict>
        <key>idVendor</key>
        <integer>1234</integer>
      </dict>
    </array>
    <key>com.apple.developer.team-identifier</key>
    <string>ABC123456</string>
    <key>get-task-allow</key>
    <false/>
  </dict>
</plist>

Let me know if anything looks incorrect or if further clarification is needed.

Thanks!

Accepted Answer

Below are the Info.plist, entitlements, and App Store profiles for our driver and client app.

So, as a quick side comment, when looking into an issue like this, it's critical to look at the actual Info.plist file, not just the Xcode project settings. I happened to have been sent your DEXT by one of our evangelists, but without the actual data, I probably wouldn't have thought of this.

In any case, here is the CFBundleVersion of your development DEXT:

CFBundleVersion = 1

And here is your TestFlight version:

CFBundleVersion = 3433099.287482533

You can read the full details here, but that second version simply will not work in a DEXT/KEXT.

I suspect that's the problem here, but covering a few odds and ends:

  1. Our driver’s Info.plist specifies both idVendor and idProduct, but our entitlements and provisioning profiles currently include only the idVendor. Do we need to request approval or entitlement inclusion for the idProduct as well?

No. There are actually two mechanisms at work here that operate independently.

  1. Your codesign configuration determines what device you’re "eligible" to be matched with. In your case, that means your DEXT is a candidate to be loaded for any USB device with an idVendor = 1234. This is what controls whether or not the kernel "sees" your DEXT for any given device.

  2. The contents of your IOKitPersonalities are what the kernel ACTUALLY uses for matching. In your case, that means that this particular DEXT will match with a device that has this configuration:

bConfigurationValue = 1
bInterfaceNumber = 0
idProduct = 5678
idVendor = 1234

It's actually fairly normal for #1 to be significantly broader than #2, as that's how vendors ship different drivers for different hardware without needing a different entitlement set for EVERY single device they ship.

  1. We’ve noticed that our development provisioning profiles use wildcard matching for idVendor:

This is normal, as this is how the development only variants allow matching to "any" hardware.

Is there a way to update our development profiles to match the App Store versions?

Theoretically, yes. In theory, you could generate manual provisioning profiles for the DEXT and then switch to "manual" codesigning in Xcode. However, I would strongly recommend against doing so. When it comes to DEXT signing, there are basically two cases in Xcode 16:

  1. Your team configuration is simple enough that automatic code-signing actually works.

  2. Your team configuration is complex enough that distribution signing breaks, forcing you to manually sign distribution builds.

In the first case, you should enjoy that fact and ignore this issue. In the second case, you should celebrate the fact that at least you don't have to deal with development builds... and ignore this issue.

One thing to understand here is what "wrongly" signed would actually mean. There are basically two cases:

  1. Your entitlement is misconfigured in a way that makes your DEXT nonfunctional. For example, if your entitlement is configured as "idVendor=4321" but your hardware is "idVendor=1234", then that DEXT is incapable of EVER actually running against hardware. This is a case you might want to check for, but it's not something that will really "break" once it's been properly configured on our side.

  2. "Something" about your configuration is "wrong" that makes your app signing configuration incapable of running.

My experience has been that, at least for DEXT, all signing errors seem to happen at build time, NOT install or run time. That is, once you get a DEXT signed it won't fail because of codesigning. That's definitely the case here, as that KEXT version check is basically as old as the system is.

__
Kevin Elliott
DTS Engineer, CoreOS/Hardware

We were able to resolve the build issues, and the driver is now working correctly on TestFlight. Here are some details:

  1. It turns out that the xcodebuild -exportArchive step was overwriting our dext’s build number to match the app build number (e.g., 3433099.287482533). We set the manageAppVersionAndBuildNumber flag to false in our ExportOptions.plist to prevent Xcode from syncing the driver’s build number, and that resolved the issue.

  2. For the provisioning profile mismatch between development and App Store builds, we followed the recommendation to use separate entitlement configurations for normal and ipa (distribution) builds. That change made automatic signing work as expected.

Really appreciate your help!

It turns out that the xcodebuild -exportArchive step was overwriting our dext’s build number to match the app build number (e.g., 3433099.287482533). We set the manageAppVersionAndBuildNumber flag to false in our ExportOptions.plist to prevent Xcode from syncing the driver’s build number, and that resolved the issue.

I didn't get into specifics because I was pretty sure there were configuration possibilities I didn't know about, and you've proven that my instinct was correct.

For the provisioning profile mismatch between development and App Store builds, we followed the recommendation to use separate entitlement configurations for normal and IPA (distribution) builds. That change made automatic signing work as expected.

Great, thanks for letting me know! I wasn't sure that build archiving would handle this properly, and I'm happy to be proven wrong.
__
Kevin Elliott
DTS Engineering, CoreOS/Hardware

DriverKit issue with TestFlight
 
 
Q