Post

Replies

Boosts

Views

Activity

Reply to setCodeSigningRequirement seems not to work in new Service Management API setup.
I just tried the example I shared with you with Hardened Runtime enabled, it seems to be working fine. When I said XPC stops working, I meant the service fails to launch and reply, sorry I don't have error details right now. At present I cannot reproduce it with the sample I shared. I was getting it with the project I was working on. I am surprised with the result, I clearly remember calls failing, may be I did really something stupid and assumed it does not works. I'll revisit the project and check again, in case I am able to reproduce the issue, I'll start a new thread. Thanks for your efforts in helping with the setCodeSigningRequirement issue, really appreciate.
Topic: Privacy & Security SubTopic: General Tags:
Apr ’25
Reply to setCodeSigningRequirement seems not to work in new Service Management API setup.
ok, no issues, I'll await your response. Aim of Installer (that I want to achieve using mechanism discussed above): Copy files packaged within app to root protected directory by launch daemon. Execute command line to install auth plugin and take backup of current setup, for rollback. (via installer launch daemon) Execute command line to install launch daemon for(paired) auth plugin (via installer launch daemon) Execute command line to store secret in system keychain (via installer launch daemon) First time app installs auth plugin and other artefacts, on next launch helps manage them. (installation + management) I mention this as you noted above I am not using Hardened Runtime, if I do app's launch daemon fail to work. If hardened runtime is not used it will not get Notarised, I am in a fix here. Also call to setCodeSigningRequirement is in question.
Topic: Privacy & Security SubTopic: General Tags:
Apr ’25
Reply to setCodeSigningRequirement seems not to work in new Service Management API setup.
I have prepared the sample, the launch daemon is packaged inside the app. The app requires launch daemon's plist and binary to be located inside the app and specified location, which is controlled by Build Settings. I tried this example and my own project with Hardened Runtime and it does not works. The original example that I took from Apple Developer's website also did not include it and hence I did not opt for it too earlier. I commented the code that calls setCodeSigningRequirement. I have also commented SwiftUI preview as it will eager load daemon during preview. Currently I am calling register service in constructor hence the issue, I do it differently in project. Debugging launch daemon at times is difficult main need being to understand why it is not starting, but launch daemon inside the app is much more challenging, if it fails to start for some reason, digging logs in console.app is hard. Just a view point. When you launch the app there is single button on click of it you should get back response from XPC provider what is its pid. The demo app is uploaded here.
Topic: Privacy & Security SubTopic: General Tags:
Mar ’25
Reply to setCodeSigningRequirement seems not to work in new Service Management API setup.
Running which app? The client? An XPC server? Or both? The app from Updating your app package installer to use the new Service Management API provides a way to package your app (main app + XPC Client) along with the launch daemon inside it, it is not global. So when I am running the main app it launches and I call following. static let ServicePlist = "com.company.usecase.daemon.plist" class func register() { let service = SMAppService.daemon(plistName: ServicePlist) do { try service.register() print("Successfully registered \(service)") } catch { print("Unable to register \(error)") exit(1) } } This registers the launch daemon in the system. The plist and launch daemon binary is packaged inside the app's Contents folder. The plist has entry where to find launch daemon binary inside the app. Once the service is up, I have a button on click of it I simply get a response from the service. I run the app from Xcode, the app shows up, on init in background I register the service, I click on a button and it triggers the service. Give me some time I'll prepare a sample and share here. Thanks for the response, it cleared some doubts, for more I'll share code soon.
Topic: Privacy & Security SubTopic: General Tags:
Mar ’25
Reply to setCodeSigningRequirement seems not to work in new Service Management API setup.
Forgot to mention, I am using almost the same setup from Security Authorisation Plugin, I have XPC client inside Authorisation Plugin which will be talking to XPS Service inside a normal/global setup daemon. In this discussion setCodeSigningRequirement and Security Agent Plugins, it is mentioned there is some bug and feedback was raised, however clicking on it there is no information, I am not sure how to figure out how things will play in Security Authorisation plugin.
Topic: Privacy & Security SubTopic: General Tags:
Mar ’25
Reply to MacOS Authorisation Plugin Installation Strategy
Thanks for the above response it cleared doubts I had regards to distribution, however I have concerns over how to make an installer. I found this Updating your app package installer to use the new Service Management API. As during installation I have to talk to remote server and also place files in privileged location, I was not clear how to approach this. What I read .pkg cannot have highly customised UI and also all work needs to be done in scripts (shell) which seemed limited. With above link I think I got some idea, with SM API I can package an app which can talk to launch daemon which resides inside my app and can do privileged actions of installing my auth plugin. I still have to pursue it and see it in action. Mostly, I have been doing simple macOS and iOS apps, never faced these challenges so was confused how to approach things. Install Flow: Talk To Remote Server -> Fetch some keys -> Install auth plugin and launch daemon which will help auth plugin -> Store fetched keys in System Keychain. Above will initialise my auth plugin and it will be ready to use on next restart.
Topic: Privacy & Security SubTopic: General Tags:
Mar ’25
Reply to MacOS Authorsation Plugin and Protected System Keychain Entry.
Please ignore I was not looking into it correctly, -w option of security command I missed. I am able to get a launch daemon going and talk to it over XPC. However I am still struggling with Key Chain entry. I am using below code as one of the XPC endpoints. let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrAccount as String: "testDaemon", kSecAttrService as String: "com.garrow.cred.daemon.xpc", kSecValueData as String: "mypass" ] // Remove for now SecItemDelete(query as CFDictionary) et status = SecItemAdd(query as CFDictionary, nil) This works, I mean no errors. sudo security find-generic-password -a testDaemon -s com.garrow.cred.daemon.xpc shows entry is in System Keychain. keychain: "/Library/Keychains/System.keychain" version: 256 But I can access it without sudo as follows too. security find-generic-password -a testDaemon -s com.garrow.cred.daemon.xpc Question: I have no clue how to block this. I am fine someone can access it with sudo or as discussed anything run as root, but even non root access, how to stop this? I searched over internet but most examples cover scenario where Key Chain access is all about in reference to an iOS or macOS application. People have logged in and they want to protect passwords for their app, System Keychain I cannot find any good resource. Some suggest to use security command as last discussed but I don't want to and that too with -T "". Please advice.
Topic: Privacy & Security SubTopic: General Tags:
Mar ’25
Reply to MacOS Authorsation Plugin and Protected System Keychain Entry.
Quinn, Thanks for the response and I could follow it well. Taking your advice I am using following option. My advice is that you not do the latter. If you need this item in a non-privileged mechanism, have a privileged mechanism that gets this keychain item and put its into the authorisation context. However, I am finding it difficult to quickly prototype (command line) logic to add entry into System Keychain. I found some examples but it seems to be using deprecated API. Only thing that seems to be working is using security command line tool as. I plan to run the below command as simple Process#launch. I tried it in authorisation plugin to run something else which gave result, hoping will work fine for below command. sudo security add-generic-password -a root -s "MySecureEntry" -w "my-secret-value" -T "" /Library/Keychains/System.keychain Note, -T "" Without giving it, the below program can read the value without sudo. I can read that entry in root context as follows (command line app run with sudo). func getKeychainEntry(service: String, account: String) -> String? { let query: [String: Any] = [ kSecClass as String: kSecClassGenericPassword, kSecAttrService as String: service, kSecAttrAccount as String: account, kSecReturnData as String: true ] var dataRef: AnyObject? let status = SecItemCopyMatching(query as CFDictionary, &dataRef) if status == errSecSuccess, let data = dataRef as? Data { return String(data: data, encoding: .utf8) } else { print("Failed to retrieve from Keychain: \(status)") return nil } } I am not feeling good about what I am doing above, is there a better way? Apologies if question feels silly.
Topic: Privacy & Security SubTopic: General Tags:
Mar ’25