sweetpad-dev / sweetpad

Develop Swift/iOS projects using VSCode
https://marketplace.visualstudio.com/items?itemName=sweetpad.sweetpad
MIT License
574 stars 19 forks source link

macOS app entitlements issue #47

Open cameroncooke opened 1 month ago

cameroncooke commented 1 month ago

Hello,

I'm having problems running a macOS app that needs specific entitlements for calendar access. The project runs perfectly in Xcode and I can request calendar permissions. When using sweetpad the request authorisation option doesn't work I get the error in the Console.app:

Prompting policy for hardened runtime; service: kTCCServiceCalendar requires entitlement com.apple.security.personal-information.calendars but it is missing

I have the entitlements file in my project root and tried add the build argument to settings.json:

    "sweetpad.build.args": [
      "-skipMacroValidation",
       "CODE_SIGN_ENTITLEMENTS=MyApp/MyApp.entitlements"
    ],

While this adds the argument this doesn't work either. ~Looking at the Xcode Build logs it appears Xcode is signing the macOS app due to the hardened runtime/app sandbox.~

I know the project is correctly configured as it works perfectly in Xcode so I assume this is an xcodebuild/signing issue.

~How can I ensure my app is code-signed when using sweetpad?~

Update:

The issue relates to how the macOS apps launch as a sub-process of vscode. It appears that the launch process (Vscode) is expected to have the entitlements that are required for the built application. This is likely because of the way macOS builds are launched from the integrated terminal.

Launching the app build from the system terminal or via open commends resolves the issue but then then there is no way to capture stdout and stderror.

One solution I've found that works and meets the limitations above is to use lldb to "launch" the app and attach a debugging session. While the debugging session is a side effect here, the lldb process can launch the app without it being treated as a sub-process, therefore resolving the entitlements issues as well as capturing stderr and stdout which is needed for vscode integration.

The downside is that you have to launch with a debug session. That said I don't see this as a limitation as that is what most developers expect when building and running anyway.

I propose a new build and debug option (additive change) that can be used which in turn resolves these issues for macOS apps that require entitlements.

cameroncooke commented 1 month ago

So I've hit a dead end with this, it seems that my macOS app is not fully trusted when launched directly by vscode. The only way I've managed to get this working is by launching it via another process that's outside of Cursor i.e. system terminal using open command. Still, when doing this there is no way to capture stderr and stdout to capture log output in vscode.

It does however work when the app is launched via an lldb debugging session, again this is likely because the debugger is launching the app not vscode.

Ideally, I would like a vscode task to build and debug so that the debugger launches the app. This also ensures logouts are correctly captured.

This would also be closer to how the Xcode "Run" command works, which builds and launches via a debug session by default.

hyzyla commented 1 month ago

I am very thankful for the effort and valuable insights that you've provided. I use ControlRoom to test how a macOS app works with my extension. However, I have an issue where there is no stdout/stderr output, and I have never encountered any problems with entitlements. If you have time, could you check if you can reproduce this error with the app? Could you also create and share a super simple example of a macOS project with the same issue?

cameroncooke commented 1 month ago

Attached is an example project.

A couple of notes:

Looking in system console we can see when pressing the button (when launched via vscode) we get:

Prompting policy for hardened runtime; service: kTCCServiceCalendar requires entitlement com.apple.security.personal-information.calendars but it is missing for responsible={TCCDProcess: identifier=com.todesktop.230313mzl4w4u92, pid=18388, auid=501, euid=501, responsible_path=/Applications/Cursor.app/Contents/MacOS/Cursor, binary_path=/Applications/Cursor.app/Contents/MacOS/Cursor}, accessing={TCCDProcess: identifier=com.cameroncooke.EntitlementExample, pid=54814, auid=501, euid=501, binary_path=/Users/cameroncooke/Library/Developer/Xcode/DerivedData/EntitlementExample-frpmjxypzqubhfdrchzmhtjbvjil/Build/Products/Debug/EntitlementExample.app/Contents/MacOS/EntitlementExample}, requesting={TCCDProcess: identifier=com.apple.calaccessd, pid=673, auid=501, euid=501, binary_path=/System/Library/PrivateFrameworks/CalendarDaemon.framework/Support/calaccessd},

It appears that calaccessd is treating Cursor (Vscode) as the source process to which should have calendar entitlements and not the launched application.

The solution it would seem is to launch the app from a trusted process like lldb which I've proven to work in my testing when configuring SweetPad to programmatically run a debugging session using launch instead of attach.

The default debug provider that SweetPad creates uses the attach option which requires the app to be launched already, which just conflates the issue as vscode launching the app is the issue I'm having.

EntitlementExample.zip

cameroncooke commented 1 month ago

I've attempted to add a run (inc. build) and debug option to SweetPad see: https://github.com/cameroncooke/sweetpad/tree/run_and_debug but I'm not happy with it as I really don't know enough about how debugging works in vscode/sweetpad.

The idea being that debugger will LAUNCH the app with a debug session instead of ATTACH to an existing session.

cameroncooke commented 1 month ago

I'm pretty sure the issue is because the integrated terminal is running as a subprocess of vscode so inherits the security context.

cameroncooke commented 3 weeks ago

@hyzyla any thoughts on this I guess the issue is not so much code-signing but macOS build support, while some trival apps will be fine apps with entitlements won't be, so it would be great to find a solution. What did you think about my idea of adding a build and debug option as this resolves the issues for me as long as lldb launches the app when attaching the debugger?

kovyrin commented 1 week ago

Thank you for outlining the issue here. Hit exactly the same problem with my app today (while trying to switch from XCode to Cursor for my development) and was a bit confused as to why the app that worked yesterday suddenly started failing when executed from within Cursor.