Service Management

RSS for tag

The Service Management framework provides facilities to load and unload launched services and read and modify launched dictionaries from within an application.

Posts under Service Management tag

86 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

SMAppService: registerAndReturnError fails with Codesigning failure loading plist code: -67054
When registering the LaunchDaemons of the application using SMAppService:registerAndReturnError, I am seeing the below error. The operation couldn’t be completed. Codesigning failure loading plist: <plist name> code: -67054 Above issue is seen only on Ventura 13.0.1 and Ventura 13.1 versions. It is working fine on Ventura 13.5, Ventura 13.6 and Sonoma 14.2 as well. When I checked the system logs using sudo log stream --debug --info --predicate "process in { '<my process>', 'smd', 'backgroundtaskmanagementd'} and sender in {'ServiceManagement', 'BackgroundTaskManagement', 'smd', 'backgroundtaskmanagementd'}" I see below error 2024-02-27 16:02:22.382487+0530 0x4c006 Error 0x0 321 0 smd: [com.apple.libxpc.SMAppServiceShared:all] Static code signature check failed: -67054 2024-02-27 16:02:22.382500+0530 0x4c006 Error 0x0 321 0 smd: [com.apple.libxpc.SMAppServiceShared:all] Unable to validate code signature on bundle for <private>. Code: -67054 2024-02-27 16:02:22.384288+0530 0x4c006 Error 0x0 321 0 smd: [com.apple.xpc.smd:SMAppServiceFactory] Unable to load plist: <private> subpath: <private> status: -67054 There is no difference in the code between. There is no modification to the application bundle after codesigning in both cases (working and not working). Can someone let me know why is there a difference in the behavior in the earlier Ventura versions? Any steps to debug and resolve this issue would be highly appreciated. Thanks
1
0
622
Mar ’24
Entitlement to write preference that includes a device specific identifier
Since the macOS 14.2 update, services installed with SMAppService are required to be sandboxed when the main app is sandboxed as well (113037504). I had developed a daemon to communicate with the pmset interface, as that requires root privileges to make changes. Since the macOS 14.2 this daemon executable has to be sandboxed as well if I want my main app to be sandboxed. When sandboxing the daemon, it requires a temporary exception entitlement as the pmset command writes to one of the following two preference located in /Library/Preferences/: com.apple.PowerManagement.plist com.apple.PowerManagement.{UUID}.plist The specific command I use writes to the latter, which includes some specific UUID, that is specific to that device. When I use the: com.apple.security.temporary-exception.shared-preference.read-write entitlement with com.apple.PowerManagement.0000 where 0000 is the exact UUID string as on my Mac, the daemon is able successfully use the pmset command. This results however in that on other user devices it would not work as the UUID in the preference name would be different. When I try setting it to a wildcard variation such as com.apple.PowerManagement.*, the command doesn't run anymore as this format for the exception entitlement seems to be unsupported. My question is now, is there any way to get an exception entitlement which accounts for the unique identifier or is that impossible and must I disable the sandbox altogether? (as I have to use a daemon, I am not developing for the Mac App Store and a sandbox isn't strictly necessary so it wouldn't break my app. Its more I would prefer to use sandboxing if possible) Thanks in advance! For reference, this is the error I get when the entitlement is set incorrectly or not set: rejecting write of key(s) AC Power in { com.apple.PowerManagement.0000, kCFPreferencesAnyUser, kCFPreferencesCurrentHost, /Library/Preferences/com.apple.PowerManagement.0000.plist, managed: 0 } from process 15694 (pmset) because setting preferences outside an application's container requires user-preference-write or file-write-data sandbox access
1
0
693
Feb ’24
Migrating from pkg installer to Service Management
Hello, we are currently working on a plan to migrate our app suite from Developer ID binaries inside a simple pkg installer to macOS app store distribution. The reason we are using an installer is that there are multiple binaries inside that communicate via XPC and we need to install the respective launchd plist in /Library/LaunchDaemons and /Library/LaunchAgents: 1 root daemon 1 agent that has minimal UI and lives in the system menu bar 1 embedded command line utility in user agent 1 embedded FileProvider extension in user agent 1 embedded Action Extension in user agent 1 agent that only does OAuth stuff Looking through Updating helper executables from earlier versions of macOS I can install the root daemon with SMAppService.daemon(plistName:) and the OAuth helper with SMAppService.agent(plistName:). For the main application I only found SMAppService.mainApp which does not accept a property list configuration. Therefore, I have no place to put my MachServices array and so the File Provider extension, the Action Extension, and the embedded command line utility have no way to talk to the user agent. Currently, XPC is used in between these processes: user agent -> root daemon command line utility -> user agent action extension -> user agent file provider extension -> user agent user agent -> file provider extension: that already works through NSFileProviderServicing I know app-to-app communication only works through launchd for security reasons, but these applications are all part of the same app group (except the root daemon obviously). My question is what is the proper way of starting the user agent so XPC from other binaries just work ™️? Any input is much appreciated!
6
0
905
Sep ’24
SMAppService.agent.register() will launch a second instance of an application
Because I can't find a way to share StoreKit purchases between two apps (macOS), I was forced to make my LSUIElement application a single app. This is turning out to work reasonably well, except for one issue that I hadn't noticed before (maybe it's new in 14.2?). The normal flow is this: User double-clicks app icon App calls SMAppService.agent(plistName: "com.myagent.plist").register(). The referenced plist points to the same application binary (see attached project) that the user launched in step 1. System launches a second instance of the application binary What I want the call to do instead is see that the app is already running, and just adopt it (that is, if it is killed or crashes, relaunch it). I see two inelegant workarounds: Wait until the user is done configuring the app after first launch, register the app and then quit. Thing is, I can't be sure when they're done, e.g. if they don't close the window. Allow both instances of the app to run, but quit if they close the window and it wasn't launched by launchd, or if there are other instances running. This feels fragile (e.g. if the behavior of register() is ever improved as I'd like). The best solution, of course, would be to share StoreKit context between apps, so I could separate this into the UI app and background agent. (To Apple: I've filed FB13574819 with my project attached.)
0
0
546
Feb ’24
Re-registering a LaunchAgent does nothing
I have an application which uses Service Management framework to register a LaunchAgent. The LaunchAgent registers a mach service with a specific name and it listens for connections made by my application. Also the agent is registered relative to the app bundle using BundleProgram parameter in the agent plist. My problem is that after the initial registration the service always points to the path where my app bundle was located in the time of registration. Here is an example: I download my app from the AppStore and it places it in the /Applications directory. I open it and my service is registered. Then when I want to develop/debug/etc.. from Xcode I build the same app with the same service and I re-register the service from my Debug build and the service still points to the service in the /Applications directory. I tried the use case when I have two builds of my app with a different CFBundleVersion. The LaunchAgent version was the same as the version which made the initial registration, i.e. no matter which app version I use and that I re-register my service, still the initial registered version of the service is used. Based on the documentation in SMAppService.h: If an app updates either the plist or the executable for a LaunchAgent or LaunchDaemon, the SMAppService must be re-registered or it may not launch. It is recommended to also call unregister before re-registering if the executable has been changed. I think that re-registering the application should work in the aforementioned use cases. The only workaround I have found so far is: delete the application which made the initial registration of the service log out log in and open the desired app version and register the service with that version. Does anyone have the same problem and is there a more correct way to handle this use case? Is there a problem in the way I'm using the ServiceManagement framework? Should I write a feedback report to Apple about this problem?
2
0
585
Jan ’24
Application running a daemon, what about uninstalling?
I have a application that is only the UI for a daemon service. The daemon itself is runnning ok, so far. Now when the user moves the App to trash bin, will the daemon also be uninstalled? How does most MacOS software does that behind the scenes? Like, MS Teams, it runs a daeamon but when the user removes the app the daeamon should be also removed. I am using Packages for installing, so I can for example update, but differently from Windows we normally don`t have an uninstall program. I would appreciate any explanation on that, as for my research I was able to find only how to create daemons.
4
0
860
Feb ’24
My launchd scripts are not run after boot but after login
I want to start a shell script during the boot of a MacOS (14.2.1) machine. But the scripts is executed only when I log in, not directly after the system has started. I wrote a plist definition like this: > ls -l /Library/LaunchDaemons/com.foobar.justLog.plist -rw-r--r--@ 1 root wheel 397 Jan 25 21:06 /Library/LaunchDaemons/com.foobar.justLog.plist > cat /Library/LaunchDaemons/com.foobar.justLog.plist <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.foobar.justLog</string> <key>RunAtLoad</key> <true/> <key>Program</key> <string>/usr/local/bin/justLog.sh</string> </dict> </plist> > The referenced shell script looks like this: > ls -l /usr/local/bin/justLog.sh -rwxr-xr-x@ 1 root wheel 105 Jan 25 14:46 /usr/local/bin/justLog.sh > cat /usr/local/bin/justLog.sh #!/bin/bash while true ;do echo "Started script $0 as user $(whoami) in $PWD ($(date))" sleep 120 done > Then I shutdown the mac and restarted it at 21:46:40. I waited until 21:48:00 before I logged on with my default user. I was expecting my script to be run after the machine startet. But when I check the files in /var/log/com.apple.xpc.launchd I see that there are no entries from launchd during the initial boot. It looks like launchd does nothing before the first user logs in. That's not the behaviour I would expect from a script to be run when the system boots. > for i in 5 6 7 8 ;do echo "inspecting minute: 21:4$i"; grep "2024-01-25 21:4${i}:" /var/log/com.apple.xpc.launchd/launchd.log{.2,.1,} /var/log/* 2>/dev/null | wc -l ;done inspecting minute: 21:45 11747 inspecting minute: 21:46 0 inspecting minute: 21:47 0 inspecting minute: 21:48 21150 > Can anyone explain why my script is not executed before I log in?
1
0
550
Jan ’24
Setup LaunchAgent in Xcode
Hi there :) I try to put an Xcode project in place within a LaunchAgent. The ultimate goal is to have an "application" with two component: macOS application with just an basic UI all the logic happens in a LaunchAgent that runs on background and is launch at startup. The macOS app uses XPC to send messages to the agent that will run either the app is opened or not. I struggled at first having this error (for the agent): An XPC Service cannot be run directly. Then I found using MachServices key in the .plist of the agent fixes the issue, plus: let listener = NSXPCListener.init(machServiceName: "com.tonygo.NetworkMonitorAgent") Then I wonder: Do we have somewhere a documentation about how to setup a LaunchAgent in Xcode I create the plist of the agent on side and run it manually, I could do this in a more automatic way How could I package a macOS applciation that will contains the agent, install it and load the agent? Note: This is mainly for learning and understanding what we could do at each level (XPCService, LaunchAgents, LaunchDaemon, etc.).
23
0
2.5k
Feb ’24
Do we need to have a privileged helper for System extension
Platform: MacOS 12.0 I have an app bundle which contains an packet tunnel extension. I am not running my packettunnel extension in a Sandbox as I dont plan to post my app in Apple's App Store. I have an requirement to run privilege operations which I have run any place from the app. As we know the user app cannot run these privilege operations we can use the 'Service Management' api: SMJobBless to start a helper tool which can run these privileged tasks. But as I stated earlier I can run these privileged tasks from any place in the bundle, we have packettunnel extension which is running with root privileges. So looking at my above environment what would be recommended? do I really need to start a privileged helper tool or I can directly run these privileged operations from packettunnel extension? One advantage of running these privilege tasks in packettunnel extension I see is that it will not require additional an user authentication which is needed in case of using SMJobBless(), this will also avoid upgrade management of the helper tool.
1
0
643
Jan ’24
PriviledgedHelperTools - Mandatory for app function?
Greetings all, I have installed 2 similar function apps (which are safe/signed e.t.c.) I run at different times, and both add items to the Login Items background section, the one is adding a background daemon and is only functioning when the switch is turned to on, while the other adds a PriviledgedHelperTool and can function even if the switch is turned to off, but if it is turned to on, but if I run this app then somehow the other breaks and can not function properly. So as a workaround I keep the PriviledgedHelperTool switch to off and only the other app's daemon switch to on so they can both operate whenever I want. My question has to do with the one that adds the PriviledgeHelperTool, and I wonder if this script contains any crucial information for the functioning of the according application. Though even if I deleted the PriviledgedHelperTool of it from the according folder, and launched the app, it seems it was not regenerated neither any notification shown up or so. Furthermore even if I removed the PriviledgedHelperTool the app seems to function properly, but I would like that thought to be confirmed by some community experts / developers here. I am on MacBook Air M1, macOS Sonoma 14.3 Developer Beta Thank you all in advance for your time. Best regards.
1
0
397
Jan ’24
MacOS services failed to start after reboot
Hello I have an App in macOS that is based on two services The first is running as a Daemon The second running as Agent(GUI) I use a script in my app installer (postinstall) that copies the plist files into the folders /Library/LaunchDaemons /Library/LaunchAgents/ And then run for the Daemons: launchctl load And for each user who is currently connected su -c "launchctl load That is working. But when I reboot my machine only the Daemons is running The Agent is not running and in the log "launchctl" There are errors that i can not find any documentation or explanation 2024-01-04 08:01:11.047284 (gui/503 [100004]) &lt;Notice&gt;: Bootstrap by launchctl[1769] for /Library/LaunchAgents/com.sysaid.SessionUtilities.plist succeeded (0: ) 2024-01-04 08:01:11.047289 (gui/503 [100004]) &lt;Notice&gt;: exiting bootstrap mode 2024-01-04 08:01:11.047299 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: internal event: SOURCE_ATTACH, code = 0 2024-01-04 08:01:11.048031 (user/503) &lt;Notice&gt;: service inactive: com.apple.xpc.launchd.unmanaged.su.1768 2024-01-04 08:01:11.048039 (user/503) &lt;Notice&gt;: removing inactive unmanaged service: com.apple.xpc.launchd.unmanaged.su.1768 2024-01-04 08:01:11.050192 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: Requesting first run LWCR update 2024-01-04 08:01:11.064345 (pid/1759 [AgentCPP]) &lt;Notice&gt;: uncorking exec source upfront 2024-01-04 08:01:11.064352 (pid/1759 [AgentCPP]) &lt;Notice&gt;: created 2024-01-04 08:01:11.085689 (gui/503/SysAid.Agent [1771]) &lt;Error&gt;: Service could not initialize: Unable to verify trusted spawn(/Applications/SysAid Helpdesk.app/Contents/MacOS/AgentSessionUtilities, /Library/LaunchAgents/com.sysaid.SessionUtilities.plist, SysAid.Agent, 3, 503), error 0xa1 - Service cannot be launched because of BTM policy 2024-01-04 08:01:11.085697 (gui/503/SysAid.Agent [1771]) &lt;Error&gt;: initialization failure: 23C71: xpcproxy + 31472 [460][6960F486-3261-3A05-9150-1B1F72E3ADB0]: 0xa1 2024-01-04 08:01:11.085698 (gui/503/SysAid.Agent [1771]) &lt;Error&gt;: Untrusted service was denied launch by BTM. Removing. 2024-01-04 08:01:11.085699 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: internal event: INIT, code = 161 2024-01-04 08:01:11.086095 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: xpcproxy exited due to exit(78) 2024-01-04 08:01:11.086101 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: exited due to exit(78) 2024-01-04 08:01:11.086106 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: already handled failed init, ignoring 2024-01-04 08:01:11.086115 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: service state: exited 2024-01-04 08:01:11.086123 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: internal event: EXITED, code = 0 2024-01-04 08:01:11.086127 (gui/503 [100004]) &lt;Notice&gt;: service inactive: SysAid.Agent 2024-01-04 08:01:11.086131 (gui/503 [100004]) &lt;Notice&gt;: removing service: SysAid.Agent 2024-01-04 08:01:11.086151 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: internal event: PETRIFIED, code = 0 2024-01-04 08:01:11.086155 (gui/503/SysAid.Agent [1771]) &lt;Notice&gt;: service state: not running The app and the Installer signed and notarized Can you help me figure out what I'm missing
1
0
874
Jan ’24
Updating Safari content blocker from daemon
I'm building a Safari content blocker extension. The app is able to use SFContentBlockerManager.reloadContentBlocker to update the content blocker's JSON rules. However, I'm also trying to update the rules in the background through a daemon. The daemon app is embedded inside the main app, and is registered by the main app through SMAppService. The issue I'm running into is I can't get both the GUI app and the daemon to both update the content blocker: If I embed the Safari extension inside the main app and not the daemon, the main app is able to update the extension, but the daemon fails with an "operation couldn’t be completed" error (supposedly because it isn't the owner of the app) Alternatively, if I embed the extension inside the daemon, the main GUI app can no longer update the extension (also failing with "operation couldn't be completed" If I try to embed the extension inside both the main app and the daemon, it works fine when running from Xcode, but App Store Connect verification fails because it won't allow an bundle ID with two periods after the main app ID (e.g. the main app is com.example.App, the daemon is com.example.App.daemon, and the extension is com.example.App.daemon.extension) I'm wondering if I'm missing something here? Is there a way to get Safari to recognize both the main app and the daemon as "owners" of the extension? Thanks in advance!
2
1
536
Jan ’24
Can't change name "python" in Background Tasks
I have a Python script that I've configured to run every 30 minutes. Since it has an associated property list, I've been trying to modify the name that appears in the 'Allow in the Background' section, but I couldn't find an effective way to display the desired name. I tried setting the CFBundleName and CFBundleDisplayName keys in the .plist, but I don't believe they have any impact as they don't seem to change anything. Any other suggested approaches would be greatly appreciated. This is the aforementioned property list: &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt; &lt;plist version="1.0"&gt; &lt;dict&gt; &lt;key&gt;Label&lt;/key&gt; &lt;string&gt;com.tom.python-cleanup&lt;/string&gt; &lt;key&gt;CFBundleName&lt;/key&gt; &lt;string&gt;Name that i want&lt;/string&gt; &lt;key&gt;CFBundleDisplayName&lt;/key&gt; &lt;string&gt;Name that i want&lt;/string&gt; &lt;key&gt;ProgramArguments&lt;/key&gt; &lt;array&gt; &lt;string&gt;python&lt;/string&gt; &lt;string&gt;/usr/local/tom/cleanup.py&lt;/string&gt; &lt;/array&gt; &lt;key&gt;StandardOutPath&lt;/key&gt; &lt;string&gt;/usr/local/tom/cleanup-service.log&lt;/string&gt; &lt;key&gt;StandardErrorPath&lt;/key&gt; &lt;string&gt;/usr/local/tom/cleanup-service.log&lt;/string&gt; &lt;key&gt;RunAtLoad&lt;/key&gt; &lt;true/&gt; &lt;key&gt;StartCalendarInterval&lt;/key&gt; &lt;dict&gt; &lt;key&gt;Minute&lt;/key&gt; &lt;integer&gt;30&lt;/integer&gt; &lt;/dict&gt; &lt;/dict&gt; &lt;/plist&gt;
1
0
404
Jan ’24
SMAppService: When do app services get put into the "requiresApproval" state?
I work on an app which adds a login item to the user's system. I recently got a report from a user that functionality of the app that talks to the login item wasn't working; upon further investigation, it became apparent that the item was in the requiresApproval state. I plan to update the app to handle this state better, but this situation left me wondering: under what conditions do login items get put into this state immediately upon registration? The documentation mentions "the user needs to take action in System Settings before the service is eligible to run", but doesn't specify when/why this would be the case - I could guess that it's related to macOS accounts with limited privileges or restrictive MDM profiles, but would love to know for certain. Thanks!
0
0
400
Dec ’23
Can not register LaunchAgents on macOS 14.2.1
Everything is OK in previous macOS versions. But today when I call try agent.register(). I got an error: - Error Domain=SMAppServiceErrorDomain Code=1 "Operation not permitted" UserInfo={NSLocalizedFailureReason=Operation not permitted} #0 The agent is init with SMAppService.agent(plistName: ...) And I took a look for log: 2023-12-21 01:03:20.398350+0800 0x17e07 Error 0x72960 8028 0 smd: (BackgroundTaskManagement) [com.apple.backgroundtaskmanagement:main] getEffectiveDisposition: error: Error Domain=BTMErrorDomain Code=-95 "record not found" UserInfo={NSLocalizedDescription=record not found} 2023-12-21 01:03:20.398386+0800 0x17e07 Error 0x0 8028 0 smd: [com.apple.xpc.smd:SMAppService] Unable to get disposition of item: <private> error: Error Domain=NSPOSIXErrorDomain Code=3 2023-12-21 01:03:20.398407+0800 0x17e07 Default 0x0 8028 0 smd: [com.apple.xpc.smd:all] Found status: 3 for <private> 2023-12-21 01:03:46.833936+0800 0x17bcc Default 0x72949 8028 0 smd: [com.apple.xpc.smd:SMAppServiceFactory] Setting up BundleProgram keys for <private> 2023-12-21 01:03:46.833986+0800 0x17bcc Default 0x72949 8028 0 smd: [com.apple.xpc.smd:SMAppServiceFactory] Setting up BundleProgram keys for <private> 2023-12-21 01:03:46.836622+0800 0x17e05 Default 0x72949 8029 0 backgroundtaskmanagementd: [com.apple.backgroundtaskmanagement:main] registerLaunchItem: pid=8236, uid=501, type=agent, parentURL=<private>, url=<private>, config=<private> 2023-12-21 01:03:46.839123+0800 0x17e05 Debug 0x72949 8029 0 backgroundtaskmanagementd: [com.apple.backgroundtaskmanagement:main] BTMStore: save scheduled. 2023-12-21 01:03:46.839164+0800 0x17e05 Debug 0x72949 8029 0 backgroundtaskmanagementd: [com.apple.backgroundtaskmanagement:main] RecordSet notification scheduled for uid -2 2023-12-21 01:03:46.903417+0800 0x17bcc Error 0x72949 8028 0 smd: (BackgroundTaskManagement) [com.apple.backgroundtaskmanagement:main] -[BTMManager registerLaunchItemWithAuditToken:type:relativeURL:configuration:uid:]_block_invoke: error: sandbox required 2023-12-21 01:03:46.903449+0800 0x17bcc Error 0x72949 8028 0 smd: [com.apple.xpc.smd:SMAppService] Register of <private> rejected by BTM. Btw, my app is a sandboxed App.
3
2
909
Dec ’23
Execute system calls programmatically without any user intervention
I'm working on a macOS application which deals with the system calls, I want one of the calls to be shutdown executable. On click of a button, which is available in the application, the system should get shutdown. I'm able to achieve this, but everytime it is invoked, user is prompted with the sudo permission, which I want to avoid. There should not be any user intervention and the system must be shutdown. No applescript please. The user should never be prompted with the sudo permission grant and the code can be objc or swift.
1
0
436
Dec ’23