self-signed jre works in one macos account, but not another

Hi,

I have a macOS Intel machine running Ventura 13.7.4. This machine is used as a build node for Jenkins to run a test for a USB device that has an HID interface. The test runner for this is Java's junit on Azul's Zulu JDK 8 for mac. I've added the com.apple.security.device entitlement to this JDK 8 bundle and signed using a self-signed certificate. This certificate is available in the system keychain at:

keychain: "/Library/Keychains/System.keychain"
version: 256
class: 0x80001000 

On my personal account on this machine, I can run the test and it calls IOHIDDevicePlugin's open function and returns success:

    [junit] [debug] [hid.cpp:1457] HIDAccess::Open Success in open for cDeviceHandle: 0x6000006abb38

If I run the same test logged in as the Jenkins agent account, then open returns:

[junit] [debug] [hid.cpp:1484] Could not open HID with handle: 0x600002a5c018, error (-1ffffd3f): (iokit/common) privilege violation

I can see the certificate that signed the JDK bundle running the command:

security find-certificate -c "java-rt-usb" -a -m

The results are the same for both accounts. Is my setup expected to work? I.e. create a self-signed cert in one account with admin privileges, put the cert in the system keychain, sign an app bundle with a new usb entitlement using this cert, and then run that app in another account on the same machine. If it's expected to work, are there any more troubleshooting tools I can use?

ioreg shows the same output for these devices under test in both accounts:

$ ioreg -p IOUSB -w0
      +-o CMSIS-DAP@14620000  <class AppleUSBDevice, id 0x1000026ae, registered, matched, active, busy 0 (1 ms), retain 17>
      +-o CMSIS-DAP@14630000  <class AppleUSBDevice, id 0x1000026d6, registered, matched, active, busy 0 (1 ms), retain 17>
Answered by DTS Engineer in 829042022

FYI, self-signed certificates aren’t really useful for code signing on macOS. They are better than ad hoc signing, but not much. My advice is that you use Apple Development signing identities for development code.

Also, the com.apple.security.device entitlement isn’t a thing. There are two groups of entitlements relevant in this context:

The first only relevant if you’ve explicitly enabled App Sandbox. The second is relevant to all programs, because all programs should have the hardened runtime enabled. However, for testing purposes you can opt out of the hardened runtime, which disables all of its additional security checks.

Regardless, neither page list com.apple.security.device.

For HID devices there is an old school com.apple.security.device.hid entitlement, but it’s been deprecated in favour of com.apple.security.device.usb, documented here. And both of those are for App Sandbox.


Honestly, I don’t think this that any of the above is relevant to your current issue. Rather, I’d focus on this:

If I run the same test logged in as the Jenkins agent account, then open [fails]

My experience with third-party CI systems is that they tend to run programs in weird execution contexts. For example, they might switch the BSD execution context but not the macOS-specific stuff. See TN2083 Daemons and Agents for more about this concept.

So, when you say that you’re running the test logged in as the Jenkins agent, are you actually logged in? Or relying on Jenkins to log you in?

And, if use the login window to log in as the Jenkins user account on the GUI, does your program work?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

FYI, self-signed certificates aren’t really useful for code signing on macOS. They are better than ad hoc signing, but not much. My advice is that you use Apple Development signing identities for development code.

Also, the com.apple.security.device entitlement isn’t a thing. There are two groups of entitlements relevant in this context:

The first only relevant if you’ve explicitly enabled App Sandbox. The second is relevant to all programs, because all programs should have the hardened runtime enabled. However, for testing purposes you can opt out of the hardened runtime, which disables all of its additional security checks.

Regardless, neither page list com.apple.security.device.

For HID devices there is an old school com.apple.security.device.hid entitlement, but it’s been deprecated in favour of com.apple.security.device.usb, documented here. And both of those are for App Sandbox.


Honestly, I don’t think this that any of the above is relevant to your current issue. Rather, I’d focus on this:

If I run the same test logged in as the Jenkins agent account, then open [fails]

My experience with third-party CI systems is that they tend to run programs in weird execution contexts. For example, they might switch the BSD execution context but not the macOS-specific stuff. See TN2083 Daemons and Agents for more about this concept.

So, when you say that you’re running the test logged in as the Jenkins agent, are you actually logged in? Or relying on Jenkins to log you in?

And, if use the login window to log in as the Jenkins user account on the GUI, does your program work?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn for the detailed response. I'll take it item by item.

I can try with our Apple Dev identity. It's more involved with the pipeline builds, but I'll try it if you think it will help.

Also, the com.apple.security.device entitlement isn’t a thing.

Sorry, I made a mistake in my report. It was this entitlement: com.apple.security.device.usb that you mentioned later. If I run the test using a JDK bundle without that entitlement, then open fails with the same error code in my personal user account the same as the agent account with the com.apple.security.device.usb entitlement.

Here's how it looks in the xml formatted entitlements:

  <key>com.apple.security.device.usb</key>
  <true/>

So, when you say that you’re running the test logged in as the Jenkins agent, are you actually logged in? Or relying on Jenkins to log you in?

This is through Terminal and sudo su - jenkins-agent. So logged in, but not through the mac login UI.

And, if use the login window to log in as the Jenkins user account on the GUI, does your program work?

I don't have the credentials for this account since they're managed by another group. But I was able to try with a new testuser account with admin privileges and logging in directly succeeds to open HID like my personal account.

If I log in with sudo su - testuser, then it fails with the same error code as the jenkins-agent account. Is there an entitlement that would help in this scenario? Or is it better to just use the Apple Dev identity to sign the JDK?

I was able to sign the JDK with the cert that we ship products with: Apple Developer ID Application. It didn't change the outcome at all. I found that HID open works if sudo is used in the pipeline. I would rather not use that as a permanent solution since it isn't how users run our software, but maybe that helps with diagnosis.

Accepted Answer
I can try with our Apple Dev identity … if you think it will help.

I don’t think it will, and your tests seem to confirm that. This is more a general guideline that a specific workaround for your current issue.

Here's how it looks in the xml formatted entitlements

Do you also have the App Sandox enabled? Using the com.apple.security.app-sandbox entitlement? Because I’d only expect com.apple.security.device.usb to be relevant in that case.

So logged in, but not through the mac login UI.

Yeah, that’s what I suspected.

I’m not really a HID expect, but I suspect that this entitlement only works if you’re running in a GUI login context. This makes sense when you think about it; you don’t want random processes running in background contexts to be messing with HID devices. However, your CI system is not running in a GUI login context, and hence this problem.

If you’ve enabled the App Sandbox, you could try disabling it. That might help. If not, the only good answer I see is to reconfigure your CI system to run a GUI login context.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

I’m not really a HID expect, but I suspect that this entitlement only works if you’re running in a GUI login context. This makes sense when you think about it; you don’t want random processes running in background contexts to be messing with HID devices. However, your CI system is not running in a GUI login context, and hence this problem.

I was able to corroborate this today. The test (HID open) for my logged in personal account was only working over SSH because I also had a screen share to this machine (remote CI node) at the same time. If I only ssh to this machine without GUI login, then the test fails for my personal account just like the CI agent. It looks like the only practical way around it for my needs is sudo. It's good to understand the why at least.

If you’ve enabled the App Sandbox, you could try disabling it. That might help. If not, the only good answer I see is to reconfigure your CI system to run a GUI login context.

It's a nice suggestion. I may pursue that idea in a GUI driven test at some point in the future.

Thanks for all your help on this.

self-signed jre works in one macos account, but not another
 
 
Q