27 Replies
      Latest reply on Feb 19, 2020 2:04 PM by MCCZ
      MCCZ Level 1 Level 1 (0 points)

        Hi,

         

        I am creating a plug-in written in a combination of Objective-C and Swift. As such, the bundle contains the following structure:

        /Contents/Frameworks/libswiftCore.dylib (and few other Swift's dylib files)

        /Contents/Info.plist

        /Contents/MacOS/MainProductBinary

        /Contents/Resources/ - contains pdfs, nibs etc.

         

        1. I've codesigned and notarized each *.dylib file individually

        2. I've codesigned and notarized the bundle as a whole

        3. I've packed the bundle and transfered via web (so it becomes quarantined) to a fresh Catalina virtual machime

        4. I've installed the third-party host application for which the our product is a plug-in onto the Catalina virtual machine

        5. I've placed the plug-in into a folder where the host application expects it

         

        When I start the host application, Gatekeeper complaines that it cannot check the bundle for malvare.

         

        I manually assess the *.dylib files using a Terminal using the commands bellow:

        for filename in MyPlugin.bundle/Contents/Frameworks/*.dylib; do
          spctl --assess --verbose=4 --type install "$filename"
        done
        
        

        After running these commands, Gatekeeper becomes satisfied and allows the plug-in to run when I start the host application.

         

        However, I'm not a supporter of an idea to force users to run these commands before installing the plug-in.

         

        Additional notes:

        - Running spctl --assess --type install on the whole bundle before manually assessing the *.dylib files reports "rejected". However, running the same command after manually assessing the *.dylib files reports "accepted".

         

        What should I do to make Gatekeeper satisfied without the need to run these commands?

        • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
          john daniel Level 4 Level 4 (570 points)

          The only thing you need to notarize is the top-level installer package. If you are doing something funky like a plug it, then it is a little more complicated. Look for any number of posts by eskimo explaining how to do it.

            • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
              MCCZ Level 1 Level 1 (0 points)

              I've tried notarizing only the outer package but I failed. As I noted in the linked thread, everything started working when I removed all dylib from the plug-in. As official docs were of no help, I've searched web and I've found lots of thread stating issues if dylib files are present but missing any answer. Then I found this thread stating that if they notarized dylib files separatedly, it helped. So I've tried that and really, it made a progress.

               

              It's strange that the assessment fails unless I perform assessment on inside files first. I would expect that manually performing assessments on inside files would not change the outcome of the bundle-wide assessment as it should be either ok or not. The behaviour I experience is quite weird to me as it reports the exactly same binaries both as rejected and as accepted.

                • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                  john daniel Level 4 Level 4 (570 points)

                  I think that since notarization requires proper signing, the author of that post assumed there was something else going on. Proper signing is all that is necessary.

                   

                  That being said, it is difficult to speculate about what is going wrong. The last few questions I've seen about notarization problems all turned out to be caused by doing something really crazy to get those dylibs inside the bundle. I'm not sure what people are doing. Look at existing plug-in bundles and notice a structural pattern that all well-written plug-ins share. Copy that structure. I've been using OS X since before day one. All of the reports of notarization problems that I've seen (yes, all of them) involve bundle structures unlike anything that I've seen in 20 years.

                   

                  Plugins are more of an outlier since they are based more on what the containing app expects to see. But surely, for every app worth having plug-ins, there have got to be some examples of properly notarized plug-ins. Find them and copy their structure. If you still have problems, then at least you will have something to reference.

              • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                eskimo Apple Staff Apple Staff (13,035 points)

                In step 3, how did you package up the you’re plug-in?

                Share and Enjoy

                Quinn “The Eskimo!”
                Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                let myEmail = "eskimo" + "1" + "@apple.com"

                  • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                    MCCZ Level 1 Level 1 (0 points)

                    1. In production, I tar czf the whole directory which contains the bundle (the parent directory contains additional files like How to PDF etc.).

                    2. While investigating, I was also trying the exactly same zip file sent for notarization by the xcrun altool --notarize-app command (the zip file was created calling ditto -c -k --keepParent --rsrc)

                      • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                        eskimo Apple Staff Apple Staff (13,035 points)

                        OK.  One factoid about both of these container formats is that they don’t support stapling.  Honestly, I’m not yet sure if that’s relevant.

                        Earlier you wrote:

                        I've tried notarizing only the outer package but I failed.

                        To be clear, notarising the outermost container (which in this case is your plug-in’s bundle) is the correct option here.  Notarising subcomponents is a bad idea in general and I’ve seen it trigger weird problems in situations similar to this.


                        If you do notarise just the outermost container, what does the notarisation log look like?  I’m specifically interested in:

                        • If there are any warnings in the issues property

                        • The list of all the paths under the ticketContents property

                        Also, what does the your plug-in layout look like?  If do you do this:

                        % find MyPlugin.bundle

                        what does it print?  I realise that may be a long list, so feel free to condense stuff that’s all going to be treated the same (for example, if Contents/Resources/ contains 27 PDFs, you can elide 26 of them).


                        Finally, one more question on a completely different tack.  Does the host app guaranteed to load your plug-in in a separate process?  Or does it load it within the host app’s process?

                        Also, what’s the deployment target for your plug-in?

                        This matters because, if the host app loads your plug-in into its own process and you support systems prior to 10.14.4, it’s not safe to use Swift in your plug-in.  In 10.14.4 we bundled the Swift runtime in the OS, so you don’t need all of those Swift libraries in the first place.  On earlier systems the Swift runtime gets loaded from your plug-in, but that’s problematic because any given process can only have one copy of the Swift runtime and you can’t guarantee that when building an in-process plug-in (the app might have its own Swift runtime, or there may be other in-process plug-ins with their own Swift runtime).

                        Share and Enjoy

                        Quinn “The Eskimo!”
                        Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                        let myEmail = "eskimo" + "1" + "@apple.com"

                          • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                            MCCZ Level 1 Level 1 (0 points)

                            After sending to a notarization service.

                            % find MyPlugin.bundle
                            MyPlugin.bundle
                            MyPlugin.bundle/Contents
                            MyPlugin.bundle/Contents/_CodeSignature
                            MyPlugin.bundle/Contents/_CodeSignature/CodeResources
                            MyPlugin.bundle/Contents/MacOS
                            MyPlugin.bundle/Contents/MacOS/MyPlugin
                            MyPlugin.bundle/Contents/Resources
                            MyPlugin.bundle/Contents/Resources/[pdf, nib, pem files]
                            MyPlugin.bundle/Contents/Resources/MyPlugin-Prefix.pch
                            MyPlugin.bundle/Contents/Frameworks
                            MyPlugin.bundle/Contents/Frameworks/libswiftObjectiveC.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftCore.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftCoreGraphics.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftDispatch.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftCoreFoundation.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftDarwin.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftIOKit.dylib
                            MyPlugin.bundle/Contents/Frameworks/libswiftFoundation.dylib
                            MyPlugin.bundle/Contents/Info.plist
                              • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                MCCZ Level 1 Level 1 (0 points)

                                Notarization log (I've just stripped jobId, uploadDate, sha256 and cdhash, renamed actual zip and bundle names to a dummy names):

                                {
                                  "logFormatVersion": 1,
                                  "status": "Accepted",
                                  "statusSummary": "Ready for distribution",
                                  "statusCode": 0,
                                  "archiveFilename": "MyPlugin.zip",
                                  "ticketContents": [
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/MacOS/MyPlugin",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftObjectiveC.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftCore.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftCoreGraphics.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftDispatch.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftCoreFoundation.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftDarwin.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftIOKit.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    },
                                    {
                                      "path": "MyPlugin.zip/MyPlugin.bundle/Contents/Frameworks/libswiftFoundation.dylib",
                                      "digestAlgorithm": "SHA-256",
                                      "arch": "x86_64"
                                    }
                                  ],
                                  "issues": null
                                }
                                  • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                    MCCZ Level 1 Level 1 (0 points)

                                    I am not sure but I think the plug-in is loaded within the host app's process.

                                    Deployment target is 10.14.

                                    Swift language version is Swift 5.

                                    I'm aware of the possible compatibility issues if different Swift runtimes are present in a process. The host app is pure Objective-C and our plug-in is the only plug-in using Swift. We re in a process of moving the Swift part to Objective-C. The replacement is not ready yet so we need to get the Swift version working in Catalina for a while.

                                      • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                        MCCZ Level 1 Level 1 (0 points)

                                        I've then copied the zip file sent to the notarization service to the 10.15 virtual machine, unzipped and run spctl --assess:

                                         

                                        % spctl --assess --type install -vvvv MyPlugin.bundle
                                        MyPlugin.bundle: rejected
                                        source=Unnotarized Developer ID
                                        origin=Developer ID Application: OurTeamName (OutTeamId)
                                        
                                        % spctl --assess --type exec -vvvv MyPlugin.bundle
                                        MyPlugin.bundle: rejected (the code is valid but does not seem to be an app)
                                        origin=Developer ID Application: OurTeamName (OutTeamId)
                                        
                                        % spctl --assess -vvvv MyPlugin.bundle
                                        MyPlugin.bundle: rejected (the code is valid but does not seem to be an app)
                                        origin=Developer ID Application: OurTeamName (OutTeamId)
                                      • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                        eskimo Apple Staff Apple Staff (13,035 points)

                                        Thanks for all the info.  To start, a simple FYI: You should not be shipping the following to users:

                                        MyPlugin.bundle/Contents/Resources/MyPlugin-Prefix.pch

                                        It’s essentially a source file.  This isn’t a problem for notarisation, it’s just a bit weird.


                                        As to what’s going wrong with your plug-in, I have a theory.  I created and notarised a test bundle here in my office.  Consider its notarisation log:

                                        {
                                          …
                                          "ticketContents": [
                                            {
                                              "path": "Test129024.dmg",
                                              "digestAlgorithm": "SHA-256",
                                              "cdhash": "359cbf51ee16eddc4e61430b2b8757abae42747b"
                                            },
                                            {
                                              "path": "Test129024.dmg/Test129024.bundle",
                                              "digestAlgorithm": "SHA-256",
                                              "cdhash": "7a5ee947ed19761162d342c4a511126cc55c8459",
                                              "arch": "x86_64"
                                            },
                                            {
                                              "path": "Test129024.dmg/Test129024.bundle/Contents/MacOS/Test129024",
                                              "digestAlgorithm": "SHA-256",
                                              "cdhash": "7a5ee947ed19761162d342c4a511126cc55c8459",
                                              "arch": "x86_64"
                                            }
                                          ],
                                          "issues": null
                                        }

                                        Note how there’s an entry for the bundle and an entry for the executable within the bundle.  In your case you only have an entry for the executable, you don’t have an entry for the bundle as a whole.  Something about your submission is causing the notary service to not recognise your bundle as a bundle.

                                        I’ve seen problems like this before where folks accidentally built their zip archive without the parent directory of their app.  However, that doesn’t look like the case here.

                                        To test this theory, I have a new diagnostic test for you: Try submitting a disk image.  To get you started, here’s the commands I used to create a disk image from my bundle:

                                        % mkdir Test129024
                                        % mv Test129024.bundle Test129024
                                        % hdiutil create -srcFolder Test129024 Test129024.dmg
                                        % codesign -s "Developer ID App" --timestamp Test129024.dmg

                                        One of two things will happen here:

                                        • The disk image’s ticket will have an entry for the overall bundle.  In that case we know there’s something wonky about your zip archive packaging.

                                        • Or it won’t, in which case we need to look at how your bundle is structured.

                                        Share and Enjoy

                                        Quinn “The Eskimo!”
                                        Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                                        let myEmail = "eskimo" + "1" + "@apple.com"

                                          • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                            MCCZ Level 1 Level 1 (0 points)

                                            Thanks for the pch recommendation. I'll remove it from the bundle after we fix the notarization.

                                             

                                            Neither the disk image's ticket has an entry for the overall bundle - it contains every entry present in the zip's ticket (the executable file and the dylib files) plus an entry for the dmg file, but not for the overall bundle. It also has issues: null.

                                             

                                            The bundle file structure is in an above reply. If I understand Bundle Structures correctly, our bundle is a Loadable Bundle and all the paths are standard and all the required files of Loadable Bundle are there.

                                             

                                            Here's the dmg content:

                                            % find /Volumes/1
                                            /Volumes/1
                                            /Volumes/1/MyPlugin.bundle
                                            /Volumes/1/MyPlugin.bundle/Contents
                                            /Volumes/1/MyPlugin.bundle/Contents/_CodeSignature
                                            /Volumes/1/MyPlugin.bundle/Contents/_CodeSignature/CodeResources
                                            /Volumes/1/MyPlugin.bundle/Contents/MacOS
                                            /Volumes/1/MyPlugin.bundle/Contents/MacOS/MyPlugin
                                            /Volumes/1/MyPlugin.bundle/Contents/Resources
                                            /Volumes/1/MyPlugin.bundle/Contents/Resources/[pdf, nib, pem files]
                                            /Volumes/1/MyPlugin.bundle/Contents/Resources/MyPlugin-Prefix.pch
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftObjectiveC.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftCore.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftCoreGraphics.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftDispatch.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftCoreFoundation.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftDarwin.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftIOKit.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Frameworks/libswiftFoundation.dylib
                                            /Volumes/1/MyPlugin.bundle/Contents/Info.plist

                                             

                                            Here's the Info.plist.
                                            / It looks exactly the same as the Info.plist file in a bundle in which I have removed all Swift code (so that bundle no longer contains the Frameworks directory) and in which the notarization works as expected - it gets notarized and makes Gatekeepr happy. /

                                            % cat Info.plist
                                            <?xml version="1.0" encoding="UTF-8"?>
                                            <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
                                            <plist version="1.0">
                                            <dict>
                                              <key>BuildMachineOSBuild</key>
                                              <string>18G3020</string>
                                              <key>CFBundleDevelopmentRegion</key>
                                              <string>en</string>
                                              <key>CFBundleExecutable</key>
                                              <string>MyPlugin</string>
                                              <key>CFBundleIdentifier</key>
                                              <string>com.MyPlugin</string>
                                              <key>CFBundleInfoDictionaryVersion</key>
                                              <string>6.0</string>
                                              <key>CFBundleName</key>
                                              <string>MyPlugin</string>
                                              <key>CFBundleShortVersionString</key>
                                              <string>1.0</string>
                                              <key>CFBundleSignature</key>
                                              <string>????</string>
                                              <key>CFBundleSupportedPlatforms</key>
                                              <array>
                                              <string>MacOSX</string>
                                              </array>
                                              <key>CFBundleVersion</key>
                                              <string>1</string>
                                              <key>DTCompiler</key>
                                              <string>com.apple.compilers.llvm.clang.1_0</string>
                                              <key>DTPlatformBuild</key>
                                              <string>11C504</string>
                                              <key>DTPlatformVersion</key>
                                              <string>GM</string>
                                              <key>DTSDKBuild</key>
                                              <string>19B90</string>
                                              <key>DTSDKName</key>
                                              <string>macosx10.15</string>
                                              <key>DTXcode</key>
                                              <string>1130</string>
                                              <key>DTXcodeBuild</key>
                                              <string>11C504</string>
                                              <key>LSMinimumSystemVersion</key>
                                              <string>10.14</string>
                                              <key>NSPrincipalClass</key>
                                              <string>MyPlugin</string>
                                            </dict>
                                            </plist>
                                            
                                            
                                            
                                • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                  john daniel Level 4 Level 4 (570 points)

                                  Maybe go back to the issue of notarizing each dylib individually. Perhaps you are doing something to corrupt them or the executable. The past couple of notarization problems that I've looked at have been caused by people doing things that are just really off-the-wall. In one instance, someone was using the command-line zip tool to unzip their own submission via altool, thereby corrupting it. In another case, someone was essentially creating their own framework format. In addition, all of their dylibs had invalid rpath paths embedded in them. I was able to reorganize the project into a proper app and get it notarized, but it failed to launch with what looked like a gatekeeper failure. But it was more of an initial loadability check that was failing.

                                   

                                  Are you doing something to those dylibs? Does your bundle "executable" have valid rpaths? You can check this with "otool -l".

                                   

                                  It looks like there is a big discrepancy between what kinds of executables a Mac will run when notarization is out of the picture, and what is necessary to pass both notarization and initial gatekeeper checks. People have become very invested in, and attached to, some crazy build practices and now notarization is breaking it. But they never should have been doing that stuff to begin with. I can't be any more specific about what "that stuff" might be. In ever single case that I've seen, it's always "You're doing what? Why?"

                                   

                                  In your case, your plugin bundle is complicating things. Have you tried running Console.app just before trying to load your plug-in? In the case above, I was able to get meaningful information about of Console. It was XProtectService that reported the problem with the rpath.

                                    • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                      MCCZ Level 1 Level 1 (0 points)

                                      The plug-in is built solely by Xcode itself. There is no script outside of Xcode nor there are "complications" intentionally added into the built process. I just call xcode archive. If theres anything non-standard or not-recommended, please, let me know what, ideally with tips how to correct it. Thanks.

                                       

                                      There are 5 build phases in Xcode:

                                      Dependencies (0 items)
                                      Compile sources (x items - m and swift files)
                                      Link Binary With Libraries (2 items - Swift and the host app SDK)
                                      Copy Bundle Resources (x items - pdf, xib, pem, pch)
                                      Copy Files (0 items)

                                       

                                      These are Release's Build Settings (I've copied everything from Build Settings - Customized - Combined):

                                      COMBINE_HIDPI_IMAGES = YES
                                      DSTROOT = (-PathWhereHostAppExpectsPlugins-)
                                      INSTALL_PATH = /
                                      MACOSX_DEPLOYMENT_TARGET = 10.14
                                      LD_RUNPATH_SEARCH_PATHS = $(inherited) @executable_path/../Frameworks @loader_path/../Frameworks
                                      DEFINES_MODULE = YES
                                      INFOPLIST_FILE = $(SRCROOT)/MyPlugin/Info.plist
                                      PRODUCT_BUNDLE_IDENTIFIER = com.MyPlugin
                                      PRODUCT_NAME = $(TARGET_NAME)
                                      WRAPPER_EXTENSION = bundle
                                      FRAMEWORK_SEARCH_PATHS = $(SYSTEM_APPS_DIR)/(-HostApp-).app/Contents/Frameworks
                                      CODE_SIGN_IDENTITY = Developer ID Application
                                      CODE_SIGN_STYLE = Manual
                                      DEVELOPMENT_TEAM = (-TeamID-)
                                      ENABLE_HARDENED_RUNTIME = YES
                                      PROVISIONING_PROFILE_SPECIFIER =
                                      GCC_PREFIX_HEADER = MyPlugin/MyPlugin-Prefix.pch
                                      CLANG_ENABLE_MODULES = YES
                                      SWIFT_OBJC_BRIDGING_HEADER = MyPlugin/MyPlugin-Bridging-Header.h
                                      SWIFT_VERSION = 5.0
                                      SWIFT_INCLUDE_PATHS =

                                       

                                      Here's what otool prints out (LC_LOAD_DYLIB and LC_RPATH only):

                                      Load command 9
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 80
                                               name @rpath/(-HostApp-).framework/Versions/A/(-HostApp-)Core (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 0.0.0
                                      compatibility version 1.0.0
                                      Load command 10
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 88
                                               name /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 23.0.0
                                      compatibility version 1.0.0
                                      Load command 11
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 96
                                               name /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 1673.126.0
                                      compatibility version 300.0.0
                                      Load command 12
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 56
                                               name /usr/lib/libobjc.A.dylib (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 228.0.0
                                      compatibility version 1.0.0
                                      Load command 13
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 56
                                               name /usr/lib/libSystem.B.dylib (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 1281.0.0
                                      compatibility version 1.0.0
                                      Load command 14
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 88
                                               name /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 1894.10.126
                                      compatibility version 45.0.0
                                      Load command 15
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 104
                                               name /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 1673.126.0
                                      compatibility version 150.0.0
                                      Load command 16
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 104
                                               name /System/Library/Frameworks/CoreGraphics.framework/Versions/A/CoreGraphics (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 1348.12.4
                                      compatibility version 64.0.0
                                      Load command 17
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 96
                                               name /System/Library/Frameworks/Security.framework/Versions/A/Security (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 59306.41.2
                                      compatibility version 1.0.0
                                      Load command 18
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 56
                                               name @rpath/libswiftCore.dylib (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 1100.8.255
                                      compatibility version 1.0.0
                                      Load command 19
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 64
                                               name @rpath/libswiftCoreGraphics.dylib (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 0.0.0
                                      compatibility version 1.0.0
                                      Load command 20
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 56
                                               name @rpath/libswiftFoundation.dylib (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 0.0.0
                                      compatibility version 1.0.0
                                      Load command 21
                                                cmd LC_LOAD_DYLIB
                                            cmdsize 56
                                               name @rpath/libswiftObjectiveC.dylib (offset 24)
                                         time stamp 2 Thu Jan  1 01:00:02 1970
                                            current version 0.0.0
                                      compatibility version 1.0.0
                                      Load command 22
                                                cmd LC_RPATH
                                            cmdsize 32
                                               path /usr/lib/swift (offset 12)
                                      Load command 23
                                                cmd LC_RPATH
                                            cmdsize 48
                                               path @executable_path/../Frameworks (offset 12)
                                      Load command 24
                                                cmd LC_RPATH
                                            cmdsize 40
                                               path @loader_path/../Frameworks (offset 12)

                                       

                                      Is everything as expected? What other places to look else for potential issues?

                                        • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                          john daniel Level 4 Level 4 (570 points)

                                          OK. This is different. I read your original post again. Can you clarify a couple of things?

                                           

                                          3. I've packed the bundle and transfered via web (so it becomes quarantined) to a fresh Catalina virtual machime

                                           

                                          How did you pack it? Are you distributing it as a pkg file?

                                           

                                          4. I've installed the third-party host application for which the our product is a plug-in onto the Catalina virtual machine

                                           

                                          Did you run the host application first?

                                           

                                          5. I've placed the plug-in into a folder where the host application expects it

                                           

                                          Where is that?

                                           

                                          Here are some possible complications...

                                          4. You are not running the host app first. Therefore, the host hasn't passed Gatekeeper yet. There could be some extra checks as part of the initial Gatekeeper check that are failing due to your differently-signed plug-in that is being loaded.

                                          5. Maybe the host application is doing it wrong. Maybe it is asking you to install the plugin inside its app bundle, thus invalidating its signature. And/or some of 4) above is still complicating things.

                                          3. Are you distributing this as a pkg file? If so, you could just run your fix as part of a post-install script. If not, you would write a custom installer (maybe even in AppleScript) that performs those tasks, in addition to installing the plugin.

                                           

                                          After a bit more research, I went ahead and tracked down the host. You didn't redact it well enough. Points 4) and 3) above are still valid. I noticed the following additional issues:

                                          1) The host app has its own plugin manager. When it downloads plugins, their signatures may be invalid or might not even exist. This may cause problems for said host app in the future. Apple has said that unsigned code will not run by default in a future version of macOS. But that's not your problem.

                                          2) Again, revisit how those Apple dylibs are getting into your bundle. Are you still codesigning and notarizing them? What if you don't do that?

                                          3) The host app provides some templates and instructions. Are you using those? Specifically, the instructions tell you to use the "--deep" flag on the codesign. That flag is frowned upon, but you might need it in this case, assuming 2) above doesn't fix it.

                                           

                                          I think eskimo's suggestion to set your deployment to 10.14.4 and omit those dylibs is probably the easiest solution. That will make your plug in available. In this market, there are likely some people running old versions so this might actually be a problem for you.

                                           

                                          If all else fails, you can use your original hack inside a pkg installer for now.

                                           

                                          Edited: The host app seems to be doing everything properly. I used:

                                          codesign -d --entitlements :- /path/to/app

                                           

                                          and the correct entitlements are there:

                                          <?xml version="1.0" encoding="UTF-8"?>

                                          <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">

                                          <plist version="1.0">

                                          <dict>

                                            <key>com.apple.security.automation.apple-events</key>

                                            <true/>

                                            <key>com.apple.security.cs.allow-unsigned-executable-memory</key>

                                            <true/>

                                            <key>com.apple.security.cs.disable-library-validation</key>

                                            <true/>

                                            <key>com.apple.security.personal-information.addressbook</key>

                                            <true/>

                                          </dict>

                                          </plist>

                                            • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                              MCCZ Level 1 Level 1 (0 points)

                                              First of all, I am going to summarize recent findings:

                                               

                                              • The notarization service does not include the overall bundle in the ticketContents list so it does not recognize the overall bundle as a candidate for notarization. It lists just the dylib files and the main executable. As said by eskimo, the overall bundle should be listed as well.
                                              • The dylib files themself do not seem to be the issue - I've changed deployment target to 14.4.4 so the swift's dylib files were no longer put into the bundle. The notarization service still did not included the overall bundle in the ticketContents list.
                                              • Sending dmg instead of zip to the notarization service result in no change (except of including the dmg file in the ticketContents list). The overall bundle ticket is still missing.

                                              As long as the eskimo is right that the overall bundle should be included in the ticketContents list, it seems that something is causing the notarization service to skip the overall bundle.

                                               

                                              3. I've packed the bundle and transfered via web (so it becomes quarantined) to a fresh Catalina virtual machime

                                               

                                              How did you pack it? Are you distributing it as a pkg file?

                                               

                                              For the sake of these tests, I were transfering the same zip file as was sent to the notarization service.

                                              When distributing to real users, the bundle is copied in a directory next to several other files, than tar-ed and gzip-ed. The server replaces a content of one "other" file found in the archive before serving it to the user while keeping other file entries intact in the stream. Little complicated but there is no known issue with this approach yet.

                                               

                                              4. I've installed the third-party host application for which the our product is a plug-in onto the Catalina virtual machine

                                               

                                              Did you run the host application first?

                                               

                                              It does not matter. I've tried both variants.

                                               

                                              5. I've placed the plug-in into a folder where the host application expects it

                                               

                                              Where is that?

                                               

                                              ~/Library/Application Support/TheApp/Plugins

                                               

                                              4. You are not running the host app first. Therefore, the host hasn't passed Gatekeeper yet. There could be some extra checks as part of the initial Gatekeeper check that are failing due to your differently-signed plug-in that is being loaded.

                                               

                                              The failure appears on subsequent app starts as well.

                                               

                                              3. Are you distributing this as a pkg file? If so, you could just run your fix as part of a post-install script. If not, you would write a custom installer (maybe even in AppleScript) that performs those tasks, in addition to installing the plugin.

                                              1) The host app has its own plugin manager. When it downloads plugins, their signatures may be invalid or might not even exist. This may cause problems for said host app in the future. Apple has said that unsigned code will not run by default in a future version of macOS. But that's not your problem.

                                               

                                              We are not distributing the plugin via the plugin manager (yet).

                                              The user downloads the plugin from our website, uncompresses and double clicks on the bundle. This starts the host app (as the host app registers itself as a handler to that file extension) and the host app copies the bundle to its plugins folder located inside its Application Support subdirectory. On start-up, the host app tries to load all the bundles presents in that directory.

                                               

                                              2) Again, revisit how those Apple dylibs are getting into your bundle. Are you still codesigning and notarizing them? What if you don't do that?

                                               

                                              I were not codesigning and notarizing the dylib files in subsequent tests. I built the app to a new separate xcarchive for subsequent tests to have a clear starting point.

                                               

                                              3) The host app provides some templates and instructions. Are you using those? Specifically, the instructions tell you to use the "--deep" flag on the codesign. That flag is frowned upon, but you might need it in this case, assuming 2) above doesn't fix it.

                                               

                                              I've tried running codesign command initially as well. Now I let the Xcode to codesign (it did some codesigning as part of xcode archive).

                                               

                                              I think eskimo's suggestion to set your deployment to 10.14.4 and omit those dylibs is probably the easiest solution. That will make your plug in available. In this market, there are likely some people running old versions so this might actually be a problem for you.

                                               

                                              It did not help. I have not tried to run it yet but I followed eskimo's answer that the overall bundle should be listed in the notarization log. So I'm checking the log whether the overall bundle entry appeared.

                                                • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                                  john daniel Level 4 Level 4 (570 points)

                                                  For the sake of these tests, I were transfering the same zip file as was sent to the notarization service.

                                                   

                                                  Did you staple the bundle? Normally, after sending that zip file to the notarization service, your next step should be to delete that zip. You don't want it. Its only purpose is to upload the bundle. Once notarization succeeds, you staple the ticket to your bundle, as described in the documentation: Customizing the Notarization Workflow. Then you create a new zip file and distribute that.

                                                   

                                                  I'm not sure what eskimo was saying above about those container formats not supporting stapling. I assume he was referring to tarballs and zipfiles. I'm not familiar with plugins, but as far as I know, they can, and should, be stapled.

                                                   

                                                  I don't know about the overall container. The only time I ever check notarization logs is when looking at other people's notarization problems here in the forums. You didn't say how you originally built this project. Did you use the host app's plug-in template? Did you use a plug-in template? I've never tried a plugin and there are many potential differences between your project and the one that eskimo tried.

                                                   

                                                  Lacking any additional information, it looks like you just weren't stapling the bundle. Try that. If it doesnt' work, review the docs again, and review the host app's docs and templates again.

                                                    • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                                      MCCZ Level 1 Level 1 (0 points)

                                                      I'm not stappling during these tests. I understand from the docs that stappling is meant mainly for offline purposes, otherwise, online checks are equal to stappling.

                                                       

                                                      Edit: I found the reason. Check my last reply to Eskimo. Thanks for your collaboration in triggering this issue.

                                                        • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                                          john daniel Level 4 Level 4 (570 points)

                                                          I have to remind you. In my second reply in this thread, I said:

                                                          The last few questions I've seen about notarization problems all turned out to be caused by doing something really crazy

                                                           

                                                          And I suggested:

                                                          Look at existing plug-in bundles and notice a structural pattern that all well-written plug-ins share. Copy that structure. I've been using OS X since before day one. All of the reports of notarization problems that I've seen (yes, all of them) involve bundle structures unlike anything that I've seen in 20 years.

                                                           

                                                          Raw bundles and plugins are edge cases. The default Xcode Bundle project includes a proper CFBundlePackageType. I would be extremely surprised to see any functional bundle on a Mac that lacks this key. Maybe, if it is missing, the OS will assume BNDL when it loads. But that doesn't imply that all Apple services will behave that way. This particular issue has actually been known for years, since Apple started using online validation for things like the Mac App Store. The official fix is to set a CFBundlePackageType.

                                                           

                                                          Humans write docs. Humans write web services. Humans write dynamic library loading code. But it is very unlikely that same human did all of that. Many people were involved over decades, with different evaluations of what structures were valid enough to be accepted.

                                                           

                                                          Until this thread, I actually didn't know about that edge case of Notarization without a stapled ticket. I suggest that you do not rely on that.

                                                            • Re: Gatekeeper does not allow a bundle to run before manually running spctl --assess of contained dylib files
                                                              MCCZ Level 1 Level 1 (0 points)

                                                              Hi, thanks for your reply. Just to make few things clear and some follow-up notes.

                                                               

                                                              - Stappling the bundle was of no help. The Gatekeeper still refused to allow the bundle to run.

                                                               

                                                              - It's the first and the only thing I have ever written for MacOS, so I have no previous experience to mine from. As such, I rely mostly on docs, sample codes and forums.

                                                               

                                                              - The linked official fix has a topic/message which is quite far from what I was experiencing. I had Info.plist included and I get no error message, so there was no chance I would ever consider looking into it.

                                                               

                                                              - If the docs are not consistent, non-existant or they use too vague language, there is a high change I would follow the version which is not correct.

                                                              - If the implementations of the same requirement are not consistent across different parts of the same product and its related services, its hard to find the cause. Xcode was happy, macOS loader was happy, Gatekeeper was sometimes happy, notarization were false-happy.

                                                              - If the docs says the field is optional, has a default value and macOS behaves like that, I expect that all the macOS-related parts and services (I consider the notarization service and the Gatekeeper as a native part of macOS) either follow the same logic or issue clear message if they are more strict. If not, I consider that as a bug, either in docs, in design or in a product.

                                                               

                                                              Either way, thanks for your collaboration. It helped me to focus on the right metric (having the overall bundle included in the logs) and to isolate the cause of the issue.