6 Replies
      Latest reply on Feb 18, 2020 12:42 AM by eskimo
      crazymacguy Level 1 Level 1 (0 points)

        Hi all,

         

        I have a command-line tool that I need to notarize.

         

        Well, actually, notarizing is the easy part.  The tool is used inside an installer package, which is inside a dmg, and when we notarize the dmg, everything inside the dmg gets notarized transparantly, which is quite nice.

         

        Except that for notarizing to pass, the tool needs secure timestamps and hardened runtime enabled.

         

        Okay, so far so good.  Documentation says that Xcode does this for us.  When in debug mode, Xcode enables get-task-allow, and we can debug the tool.  When in production mode (via archive/export), Xcode enables secure timestamps and removes get-task-allow.

         

        Except, I'm having trouble exporting the tool for production.  I can archive using `xcodebuild archive -scheme mytool -archivePath mytool`, and I get an Xcode Archive bundle that looks a lot like one would expect:

         

        $ find mytool.xcarchive

        mytool.xcarchive

        mytool.xcarchive/Products

        mytool.xcarchive/Products/usr

        mytool.xcarchive/Products/usr/local

        mytool.xcarchive/Products/usr/local/bin

        mytool.xcarchive/Products/usr/local/bin/mytool

        mytool.xcarchive/dSYMs

        mytool.xcarchive/dSYMs/mytool.dSYM

        mytool.xcarchive/dSYMs/mytool.dSYM/Contents

        mytool.xcarchive/dSYMs/mytool.dSYM/Contents/Resources

        mytool.xcarchive/dSYMs/mytool.dSYM/Contents/Resources/DWARF

        mytool.xcarchive/dSYMs/mytool.dSYM/Contents/Resources/DWARF/mytool

        mytool.xcarchive/dSYMs/mytool.dSYM/Contents/Info.plist

        mytool.xcarchive/Info.plist

         

        But then when I try to export, I get:

         

        $ xcodebuild -exportArchive -archivePath mytool.xcarchive -exportPath prod-mytool -exportOptionsPlist mytool_codesigning_options.plist

        ** EXPORT FAILED **

         

        2020-02-13 06:05:23.453 xcodebuild[54323:1508625] [MT] IDEDistribution: -[IDEDistributionLogging _createLoggingBundleAtPath:]: Created bundle at path '/var/folders/mz/kgcq5n9j7yn2s9v0ch850tz80000gq/T/mytool_2020-02-13_06-05-23.453.xcdistributionlogs'.

        2020-02-13 06:05:23.474 xcodebuild[54323:1508625] [MT] IDEDistributionMethodManager: -[IDEDistributionMethodManager orderedDistributionMethodsForTask:archive:]: Error = Error Domain=IDEDistributionMethodManagerErrorDomain Code=2 "Unknown Distribution Error" UserInfo={NSLocalizedDescription=Unknown Distribution Error}

        error: exportArchive: exportOptionsPlist error for key 'method': expected one of {}, but found developer-id

         

        Error Domain=IDEFoundationErrorDomain Code=1 "exportOptionsPlist error for key 'method': expected one of {}, but found developer-id" UserInfo={NSLocalizedDescription=exportOptionsPlist error for key 'method': expected one of {}, but found developer-id}

         

        Google says that the error is caused by the Xcode Archive not containing a normal app, and that you can't export a tool.

         

        Can I export this tool?

         

        If not, then is it still possible to take advantage of Xcode's automatic debug/production switching behavior even though I need secure timestamps and the hardened runtime turned on in production?

        • Re: Notarizing a command-line tool
          john daniel Level 4 Level 4 (600 points)

          I've never exported a tool. From the error message, it looks like it doesn't like the contents of you options plist. Can you post the contents?

          Normally I just build in release mode and copy the executable to where it needs to go. You could manually code sign at that point to give it the time stamp and hardened runtime.

            • Re: Notarizing a command-line tool
              crazymacguy Level 1 Level 1 (0 points)

              Here's the contents of my options 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>method</key>
                  <string>developer-id</string>
              </dict>
              </plist>
              

               

              What you suggest is exactly what I'm doing at the moment; the apps I can build using archive/export, and Xcode does most of everything automatically.  For the tool, I added --timestamp to OTHER_CODE_SIGN_FLAGS (only in Release mode), and I set CODE_SIGN_INJECT_BASE_ENTITLEMENTS to NO (only in Release mode), and then I simply build it in Release mode.  This approach works just fine, but results in some forking of logic in our build scripts.  To clean up our build scripts and to standardize how each Xcode target is built, I was hoping I could use archive/export for both apps and tools.

            • Re: Notarizing a command-line tool
              eskimo Apple Staff Apple Staff (13,125 points)

              Can I export this tool?

              Not using -exportArchive.  In situations like this I usually create a small script that takes as its input the .xcarchive and outputs a file that’s ‘notarisation ready’ (typically a disk image).  For hints and tips on how to manually sign your tool, see my [Signing a Mac Product For Distribution][ref] post.

              Share and Enjoy

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

                • Re: Notarizing a command-line tool
                  crazymacguy Level 1 Level 1 (0 points)

                  I've noticed that in the case of apps exported from an archive using -exportArchive, the exported copy is different than the copy inside the archive.  I don't know what the mutation is, but I'm assuming it's important.

                   

                  Unlike an app, can you yank a tool out of an archive with cp or ditto?

                    • Re: Notarizing a command-line tool
                      eskimo Apple Staff Apple Staff (13,125 points)

                      I've noticed that in the case of apps exported from an archive using -exportArchive, the exported copy is different than the copy inside the archive.

                      -exportArchive re-signs the app, which changes it.

                      can you yank a tool out of an archive with cp or ditto?

                      Yes.

                      Unlike an app

                      This is not unlike an app.  You can do this with an app as well, it’s just that with apps you can take advantage of -exportArchive.

                      Share and Enjoy

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