Gatekepper acts against .app package developed by a freelancer for our company

I am responsible for the mobile app and thus also of the apple developer and app store connect accounts of a company.

An external freelancer developed a software package for us which we aim to offer for installation and use on macOS systems of our customers; distributed exclusively outside of the Apple App Store. The software package has nothing to do with the mobile app. MacOS' Gatekeeper currently warns or even prevents our customers regarding the installation of the package on their device; pretty much as described here: https://developer.apple.com/developer-id/.

According to a previous talk with Apple's Support, the software package (.app) the Freelancer developed must be signed with one of our own certificates. As we cannot grant selective app store connect access to third persons (only for the concerned certificates), we prefer to not provide access to our entire apple developer account to the freelancer, for the sole reason of the certificate & signing process. According to previous attempts with Apples' support regarding the most feasible solution in this case, they recommended me to manage the signing of the package of the freelancer, and simply request the package from the freelancer.

I've thus generated an according Developer ID Certificate, but regarding the signing process, I'm confused. I know how signing works with mobile apps in XCode, but regarding software that is not distributed throughout the App Store on macOS, I'm unsure about the process. Also, as far as I know, the entitlements of the application are involved in the signing process. So my concern is that simply having the software package (.app) from the freelancer is not really enough to complete the signing + notarization process? Won't I need further information about the app's entitlements etc.?

I would like to have a clear solution about the procedure that is required in these cases, as online documentations and / or forums as well as previous talks with your non-technical support from Apple did not resolve the issue.

Answered by DTS Engineer in 852142022

You’re right to be careful about giving this freelancer full access to your Developer ID credentials. Those are precious, as I discuss in The Care and Feeding of Developer ID.

IMO the easiest path forward is:

  1. Add your freelancer to your team as you would for iOS.
  2. They’ll be able do day-to-day development for your team, using an Apple Developer signing identity, just like they would on iOS.
  3. When they’re done, have them do a Product > Archive and send you the resulting .xcarchive.
  4. You can import that into your Xcode organiser.
  5. And do Developer ID distribution from there.

This is a manual process but you can take various steps to automate it. Specifically:

  • xcodebuild can do the equivalent of the Product > Archive in step 3.
  • And it can also export from an archive, so you can automate the first part of step 5.
  • Finally, notarytool lets you automate the second part of step 5. See Customizing the notarization workflow.

The beginning of Creating distribution-signed code for macOS has a quick summary of the xcodebuild automation.

Note It then goes on to discuss manual code signing, but you shouldn’t need to do that if you’re developing a standard app in Xcode.

There’s an accompanying doc, Packaging Mac software for distribution, which may be more interesting to you. It talks about the steps after code signing, like packaging into a disk image and notarisation.

And if you have any follow-up questions, I’d be happy to answer them here.

Share and Enjoy

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

You’re right to be careful about giving this freelancer full access to your Developer ID credentials. Those are precious, as I discuss in The Care and Feeding of Developer ID.

IMO the easiest path forward is:

  1. Add your freelancer to your team as you would for iOS.
  2. They’ll be able do day-to-day development for your team, using an Apple Developer signing identity, just like they would on iOS.
  3. When they’re done, have them do a Product > Archive and send you the resulting .xcarchive.
  4. You can import that into your Xcode organiser.
  5. And do Developer ID distribution from there.

This is a manual process but you can take various steps to automate it. Specifically:

  • xcodebuild can do the equivalent of the Product > Archive in step 3.
  • And it can also export from an archive, so you can automate the first part of step 5.
  • Finally, notarytool lets you automate the second part of step 5. See Customizing the notarization workflow.

The beginning of Creating distribution-signed code for macOS has a quick summary of the xcodebuild automation.

Note It then goes on to discuss manual code signing, but you shouldn’t need to do that if you’re developing a standard app in Xcode.

There’s an accompanying doc, Packaging Mac software for distribution, which may be more interesting to you. It talks about the steps after code signing, like packaging into a disk image and notarisation.

And if you have any follow-up questions, I’d be happy to answer them here.

Share and Enjoy

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

Hi Quinn,

Thanks for your reply, yet I'm still a little confused, as mentioned all I've done so far is to release mobile apps through automated signing via XCode for iOS (iPhones and iPads). I am also not sure if the freelancer developed the app within XCode.

Can you maybe be more precise regarding:

  1. Regarding 1., do you mean adding the freelancer to my app store connect account? If not, where? If so, which role would you recommend, according to the principle of least needed access? You also say that we should not grant access to any certificates, so I'm a little confused by this proposition.

  2. Regarding 2., are we supposed to provide that Apple Developer Identity to him?

  3. Regarding 5., do yo mean sign codesign the app with the developer ID I generated and then notarize the app? If I understand things correctly, these two things have to be done also in the future before releasing any update, correct ?

do you mean adding the freelancer to my app store connect account?

Yes. Just like you would do for iOS.

which role would you recommend … ?

That’s a balance between what authority you want to grant them and how much time you want to spend servicing their requests for credential manipulation. Although, having said that, I’ll note that this is no different than it is for iOS.

IMPORTANT There’s one thing to watch out for here. If you make them an Admin, don’t explicitly allow them to created Developer ID certificates. See the “Create cloud-managed Developer ID certificates” row in Developer > Support > Articles > Program Roles.

You also say that we should not grant access to any certificates

There are multiple types of code-signing identities in play here:

  • Apple Development is for day-to-day development
  • Apple Distribution is for uploading to the App Store
  • Developer ID is for direct distribution on the Mac

You want to give them access to the first. You want to make sure they don’t have access to the third. As to the second, it sounds like that’s not relevant in this case.

are we supposed to provide that Apple Developer Identity to him?

If they have an appropriate role, they can creat this directly, either using the Developer website or using Xcode. See the “Submit certificate signing requests” and “Create and revoke development certificates” rows in the Developer > Support > Articles > Program Roles.

do yo mean sign codesign the app with the developer ID I generated and then notarize the app?

Yes. The mechanics of doing that depend on how you plan to package the app (installer package, disk image, zip archive) and how much automation you want. In the simplest case you can:

  1. Export the app from the Xcode organiser using the Distribute App > Direct Distribution workflow. That’ll both re-sign with your Developer ID code-signing identity and notarise.
  2. Zip up the resulting app using ditto. See Packaging Mac software for distribution for the exact command.

Things get more complex if you choose other options, but those cases are covered in some detail by:

Share and Enjoy

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

Yes. Just like you would do for iOS.

But that is exactly the problem, no? If I grant access to app store connect, they will have access to all certificates, as you cannot grant selective certificate access. And that's what you warned about in your first post, no? Or did I misunderstand you here?

As a follow-up to that, I understood now that it is clear that there is no solution to perform our signing process without granting the freelancer access to our app store connect account, correct? Hence:

That’s a balance between what authority you want to grant them and how much time you want to spend servicing their requests for credential manipulation. Although, having said that, I’ll note that this is no different than it is for iOS.

What is the role that allows the freelancer to do as you say and nothing else? I'm asking you as an expert because I cannot risk any unwanted data exposure; as we initially thought (according to initial talks with Apple Support) that we cannot grant access to our app store connect account.

they will have access to all certificates, as you cannot grant selective certificate access.

I think you’re confused by the terminology here (an industry-wide problem, alas). It’s fine to give anyone access to a certificate. It only contains a public key. To sign code you need a digital identity, aka a code-signing identity, which is a certificate and the private key that matches the public key in that certificate.

So, there’s no issue with your freelancer being able to access your Developer ID certificate [1]. What you have to protect is the matching private key.

I discuss this terminological confusion in more detail in TN3161 Inside Code Signing: Certificates

there is no solution to perform our signing process without granting the freelancer access to our app store connect account, correct?

It’s not that there’s no solution, but rather than this is the easiest solution. Your freelancer could develop your app using their team, but that makes the re-signing process much (much much much!) harder.

The re-signing process I’ve outlined, based on Xcode archives, is really easy to apply if your freelancer is working in your team. However, if they’re working in a completely different team then everything gets more complicated:

  • To start, Xcode doesn’t support this out of the box. You’d either have to manually re-sign using Terminal or do some unsupported hackery on the Xcode archive.
  • But the real problem is ancillary assets. The biggest of these is the App ID. Each App ID is assigned to a specific team. If your freelancer is working in a different team, they can’t use your App ID. They have to use one assigned to their team. And the bundle ID component of the App ID has to be unique, so you have to change the bundle ID during the re-sign process.
  • And it’s actually worse than that when you look at other assets, like app group IDs. It’s relatively easy to change an app’s bundle ID — it’s obviously visible in the Info.plist — but app group IDs tend are referenced by both the code-signing entitlements and the code itself. To support changing an app group ID during re-signing, you have to explicitly write your code to get the app group ID from an easily accessible location.
as we initially thought (according to initial talks with Apple Support) that we cannot grant access to our app store connect account.

The phrase “access to our App Store Connect account” can mean a bunch of different things. What matters is the role you grant them, as defined in Developer > Support > Articles > Program Roles. Granting them the Account Holder role would be very bad [2]. Granting them the Developer role is fine, but you’ll have to perform some admin tasks on their behalf. Granting the roles in between (App Manager and Admin) will reduce the number of admin tasks you need to do on their behalf, although you have to evaluate whether you want them to be able to do such things without your oversight.

Share and Enjoy

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

[1] In fact, you give that certificate out to the entire world every time you ship an app. Consider:

% codesign -d --extract-certificates /Applications/QProcessDock.app 
Executable=/Applications/QProcessDock.app/Contents/MacOS/QProcessDock
% openssl x509 -inform der -in codesign0 -text                     
Certificate:
    …
    Signature Algorithm: sha256WithRSAEncryption
        …
        Subject: UID=SKMME9E2Y8, CN=Developer ID Application: Quinn Quinn (SKMME9E2Y8), OU=SKMME9E2Y8, O=Quinn Quinn, C=US
        …
-----BEGIN CERTIFICATE-----
MIIFcDCCBFigAwIBAgIIA1vmlEAh100wDQYJKoZIhvcNAQELBQAweTEtMCsGA1UE
…
So9Rhg==
-----END CERTIFICATE-----

Woohoo, you’ve got Quinn’s Developer ID certificate! However, that doesn’t help you, because you don’t have my private key (hopefully :-).

[2] Technically there’s only one Account Holder, so this really means “given them your Account Holder login credentials”. And, yeah, don’t do that.

So to sum things up concretely and all in all, the required steps are:

  1. Create an Apple Development Certificate.
  2. Add the Freelancer into our Apple Account, with the role 'Developer'.
  3. Forward the private key of the Apple Development Certificiate to the Freelancer, such that he can use it to develop the macOS App in XCode on his own machine.
  4. When creating the new user, under the "Additional Resources" tab, I will have to tick "Access to Certificates, Identifiers & Profiles.", such that he can use the Apple Development Certificate.
  5. Once the Freelancer's done, he should do Product > Archive and send me the resulting .xcarchive.
  6. I create a Developer ID Certificate in my app store account for direct macOS distribution. I do not forward its private key to the Freelancer.
  7. I import the obtained .xcarchive into my XCode organizer, and do Developer ID distribution, including eventual notarization etc., from there.
Gatekepper acts against .app package developed by a freelancer for our company
 
 
Q