Stapling Error 65 (Applescript app)

Trying to notarize and AppleScript app following the instructions at Der Flounder (that are based on an Automator app).

Code Signing works fine

Notarization work fine.

However when trying to stape the successful notarization the response to:


xcrun stapler staple "/Volumes/HardDrive/MyApp.app"


is:


Processing: /Volumes/HardDrive/MyApp.app
CloudKit query for MyApp.app (2/936578f9cf6dff6314bdebeba427cac9dab3f7e8) failed due to "record not found".
Could not find base64 encoded ticket in response for 2/936578f9cf6dff6314bdebeba427cac9dab3f7e8
The staple and validate action failed! Error 65.

Did you try stapling to a dmg instead of the (applescript) app itself? Did you try without the ""

xcrun stapler staple /Users/precursor/Desktop/MyApp.dmg


Note 2018 WWDC Session 702 video that, IIRC, reviews this stuff/+more: https://developer.apple.com/videos/play/wwdc2018/702/


I thought I’d give this a go but I crashed out at the first step: When I try to code sign my newly created app, I see the following failure:

$ codesign -s "Developer ID Application" -vvv Hello.app
Developer ID Application: found in both /Users/quinn/Library/Keychains/login.keychain-db and /Users/quinn/Library/Keychains/Mac (Mr Quinn).keychain-db (this is all right)
Hello.app: resource fork, Finder information, or similar detritus not allowed

This occurs for both AppleScript apps and Automator apps )-:

How did you get past this?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Quinn,


You need to run

/usr/bin/xattr -rc /path/to/app

on it first.

There seems to be a general issue that’s specific to AppleScript apps. For example, this thread and this thread. I’m going to concentrate the discussion here, because the title of this thread makes it clear that we’re talking about AppleScript apps.

More soon…

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

I spent some time looking into this today. The response below is quite long, so I’ve broken it up into sections:

  • Reproducing the Problem

  • Extended Attributes

  • Potential Workaround

  • Conclusions

Reproducing the Problem

[This is going to be long-winded but I want to make sure we’re all on the same page here.]

  1. I used Script Editor to create a very simple script:

    display dialog "Hello Cruel World!" buttons {"OK"} default button "OK"

    .

  2. I chose View > Show Bundle Contents and set the bundle identifier to

    com.example.apple-samplecode.eskimo1.helloapplescript
    .
  3. I saved it as

    HelloAppleScript.app
    .
  4. Based on sstanley’s advice, I started looking at the extended attributes. It turns out these are only set on the top-level

    .app
    directory, so I removed them like this:
    $ xattr -c HelloAppleScript.app

    Note See the Extended Attributes section, below, for more on this.

  5. I signed my app:

    $ codesign -s "Developer ID Application" --timestamp -o runtime -f HelloAppleScript.app

    .

  6. I packaged it into a

    .zip
    :
    $ ditto -c -k --keepParent HelloAppleScript.app HelloAppleScript.zip

    .

  7. I submitted that:

    $ xcrun altool --notarize-app … --primary-bundle-id com.example.apple-samplecode.eskimo1.helloapplescript --file HelloAppleScript.zip
    2019-04-24 09:13:16.617 altool[85109:15600818] No errors uploading 'HelloAppleScript.zip'.
    RequestUUID = 68715dd4-f0e7-4aa3-97aa-603200c3a189

    IMPORTANT In all of my

    altool
    examples I’m eliding the arguments associated with authentication (
    -u
    ,
    -p
    , and
    --asc-provider
    ) because:
    • Some of that stuff is private

    • Anyone reproducing this problem will need to use different values

    • They distract from the main thrust of my example

  8. Once notarisation was complete, I tried to staple:

    $ stapler staple HelloAppleScript.app
    Processing: /Users/quinn/Desktop/HelloAppleScript.app
    CloudKit query for HelloAppleScript.app (2/ad14f76b7124843933f8f4f23e67c381151cbcc1) failed due to "record not found".
    Could not find base64 encoded ticket in response for 2/ad14f76b7124843933f8f4f23e67c381151cbcc1
    The staple and validate action failed! Error 65.

    .

  9. I got information about the notarisation:

    $ xcrun altool --notarization-info 68715dd4-f0e7-4aa3-97aa-603200c3a189 … 2019-04-24 09:15:58.076 altool[85241:15605458] No errors getting notarization info.    RequestUUID: 68715dd4-f0e7-4aa3-97aa-603200c3a189           Date: 2019-04-24 08:13:17 +0000         Status: success     LogFileURL: https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/50/6f/0f/506f0f7e-ed4d-22ac-e495-3f4094f8cf03/developer_log.json?accessKey=1556288157_6807983678672715236_D0XL4pVf5PNgZy98wygaWD9sSiwgXAMfI1%2F3emX%2Fyg%2FR6s9jSr8WkGQloCd4YT%2F4HELw%2B%2BDgD5gnfM16q36DkLHxT7bYdXJJAFp6k3JVaSyF3XdSKzbesl74dF%2FOYePZtr2O%2Bb3Y0P3XCT029FedIZ2kUVvDW%2BWEsohRR1FEnYI%3D    Status Code: 0 Status Message: Package Approved $ curl https://osxapps-ssl.itunes.apple.com/itunes-assets/Enigma123/v4/50/6f/0f/506f0f7e-ed4d-22ac-e495-3f4094f8cf03/developer_log.json?accessKey=1556288157_6807983678672715236_D0XL4pVf5PNgZy98wygaWD9sSiwgXAMfI1%2F3emX%2Fyg%2FR6s9jSr8WkGQloCd4YT%2F4HELw%2B%2BDgD5gnfM16q36DkLHxT7bYdXJJAFp6k3JVaSyF3XdSKzbesl74dF%2FOYePZtr2O%2Bb3Y0P3XCT029FedIZ2kUVvDW%2BWEsohRR1FEnYI%3D {   "logFormatVersion": 1,   "jobId": "68715dd4-f0e7-4aa3-97aa-603200c3a189",   "status": "Accepted",   "statusSummary": "Ready for distribution",   "statusCode": 0,   "archiveFilename": "HelloAppleScript.zip",   "uploadDate": "2019-04-24T08:13:17Z",   "sha256": "96bedfc03c67cef0d0ff3dfce446914f572c9248c9817ed0b4a0555c4991ba1e",   "ticketContents": [     {       "path": "HelloAppleScript.zip/HelloAppleScript.app",       "digestAlgorithm": "SHA-256",       "cdhash": "a2bbac9bb3ec09a07f4bb5e3ff4604b23bd42c98",       "arch": "i386"     },     {       "path": "HelloAppleScript.zip/HelloAppleScript.app",       "digestAlgorithm": "SHA-256",       "cdhash": "ad14f76b7124843933f8f4f23e67c381151cbcc1",       "arch": "x86_64"     },     {       "path": "HelloAppleScript.zip/HelloAppleScript.app/Contents/MacOS/applet",       "digestAlgorithm": "SHA-256",       "cdhash": "a2bbac9bb3ec09a07f4bb5e3ff4604b23bd42c98",       "arch": "i386"     },     {       "path": "HelloAppleScript.zip/HelloAppleScript.app/Contents/MacOS/applet",       "digestAlgorithm": "SHA-256",       "cdhash": "ad14f76b7124843933f8f4f23e67c381151cbcc1",       "arch": "x86_64"     }   ],   "issues": null }

    .

  10. I then dumped the code signature of my app:

    $ codesign -d -vvvv HelloAppleScript.app
    …
    CandidateCDHash sha1=249a653ee558d00cc3de586a31796b57d4850c2b
    CandidateCDHash sha256=ad14f76b7124843933f8f4f23e67c381151cbcc1
    …
    CDHash=ad14f76b7124843933f8f4f23e67c381151cbcc1
    …
    $ codesign -d -vvvv --arch=i386  HelloAppleScript.app
    …
    CandidateCDHash sha1=89d6165ec0fc5573edc2869e9c9c9fa3201c969e
    CandidateCDHash sha256=a2bbac9bb3ec09a07f4bb5e3ff4604b23bd42c98
    …
    CDHash=a2bbac9bb3ec09a07f4bb5e3ff4604b23bd42c98
    …

    Note As the app is universal, I have to dump the cdhashes for the 32-bit slice using a separate command.

As you can see, the SHA-256 cdhashes all line up, making it unclear as to why the staple operation is failing.

Extended Attributes

Before I talk about workarounds, a quick digression on extended attributes (EAs). In my tests I saw three different behaviours:

  • In some cases there were no EAs.

  • In some cases there was just the Finder info EA (

    com.apple.FinderInfo
    ).
  • In other cases I saw the above and some Spotlight ones.

I was curious as to what Finder info was being set, so I poked at this with FSMegaInfo (haven’t used that in a while!) and this is what I saw:

$ FSMegaInfo -vvvv FSGetCatalogInfo -kFSCatInfoFinderInfo,kFSCatInfoFinderXInfo HelloAppleScript.app
name    = 'HelloAppleScript.app'
catalogInfo:
    finderInfo:
        windowBounds.top    = 20556
        windowBounds.left   = 16720
        windowBounds.bottom = 27764
        windowBounds.right  = 24944
        finderFlags         = 0x0010
            kIsOnDesk      = NO
            kIsShared      = NO
            kHasNoINITs    = NO
            kHasBeenInited = NO
            kHasCustomIcon = NO
            kIsStationery  = NO
            kNameLocked    = NO
            kHasBundle     = NO
            kIsInvisible   = NO
            kIsShared      = NO
            kIsAlias       = NO
            ... and others (0x10)
        location.v          = 0
        location.h          = 0
        reservedField       = 0
    extFinderInfo:
        scrollPosition.v    = 0
        scrollPosition.h    = 0
        reserved1           = 0
        extendedFinderFlags = 0x0000
            kExtendedFlagsAreInvalid    = NO
            kExtendedFlagHasCustomBadge = NO
            kExtendedFlagObjectIsBusy   = NO
            kExtendedFlagHasRoutingInfo = NO
        reserved2           = 0
        putAwayFolderID     = 0

To start,

kFSCatInfoFinderXInfo
is uninteresting because it’s all zeroes. In contrast,
kFSCatInfoFinderInfo
has some non-zero values:
  • windowBounds
  • finderFlags

The 0x10 flag is not documented in

<Finder.h>
, and I didn’t feel the need to dig any deeper than that.

The

windowBounds
property is actually an old school Mac OS file type and creator!
FSMegaInfo
is showing a
FolderInfo
structure because, hey, this is a folder. However, it seems Script Editor has set this value to a
FileInfo
structure. If you interpret these values using that structure, you get a file type of
'APPL'
and a creator of
'aplt'
.

Potential Workaround

I spent a long time looking at the

HelloAppleScript.app
to see if I could figure out what was making the notarisation system unhappy. Alas, I was unable to turn up a smoking gun. Eventually, just to simplify the problem, I decided to submit a ‘thin’ version of the app, one with just the 64-bit Intel architecture. I did this by first thinning the executable:
$ lipo HelloAppleScript.app/Contents/MacOS/applet -thin x86_64 -output HelloAppleScript.app/Contents/MacOS/applet

and then running through the rest of the submission process described in Reproducing the Problem:

$ codesign -s "Developer ID Application" --timestamp -o runtime -f HelloAppleScript.app
HelloAppleScript.app: replacing existing signature
$ ditto -c -k --keepParent HelloAppleScript.app HelloAppleScript.zip
$ xcrun altool --notarize-app … --primary-bundle-id com.example.apple-samplecode.eskimo1.helloapplescript --file HelloAppleScript.zip
2019-04-24 09:53:19.510 altool[86047:15640346] No errors uploading 'HelloAppleScript.zip'.
RequestUUID = a595d738-90fe-4553-83f4-4671436ba6f0
$ # Wait...
$ stapler staple HelloAppleScript.app 
Processing: /Users/quinn/Desktop/HelloAppleScript.app
Processing: /Users/quinn/Desktop/HelloAppleScript.app
The staple and validate action worked!

This time the staple operation worked.

I’m not sure why this helps. I have always assumed that notarisation would be able to handle universal apps, making me suspect that this was something specific to AppleScript apps. However, I ran through the whole process with a native app (build using Xcode 9.4, because Xcode 10 no longer supports 32-bit Intel) and it also fails:

$ codesign -s "Developer ID Application" --timestamp -o runtime -f HelloUniversal.app 
HelloUniversal.app: replacing existing signature
$ ditto -c -k --keepParent HelloUniversal.app HelloUniversal.zip
$ xcrun altool --notarize-app … --primary-bundle-id com.example.apple-samplecode.eskimo1.HelloUniversal --file HelloUniversal.zip 
2019-04-24 10:42:22.533 altool[87559:15682238] No errors uploading 'HelloUniversal.zip'.
RequestUUID = 49489bd5-30d4-4045-940b-8e46aff8d29f
$ # Wait...
$ stapler staple HelloUniversal.app 
Processing: /Users/quinn/Desktop/HelloUniversal.app
CloudKit query for HelloUniversal.app (2/f6ff949f17472db79c21ccb5da359b5c10be206c) failed due to "record not found".
Could not find base64 encoded ticket in response for 2/f6ff949f17472db79c21ccb5da359b5c10be206c
The staple and validate action failed! Error 65.

That’s certainly not what I expected )-:

Conclusions

I need to do more research on this at my end but, for the moment, I think it’s reasonable for folks to use the workaround above and simply thin your AppleScript apps before signing and notarising them.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Quinn,


Thanks for a great effort!

I need to do more research on this at my end …

I raised this issue with the Notarisation team and the conclusion was that the failure to notarise universal binaries, including AppleScript apps, is definitely a bug (r. 50359696). A fix for this has been rolled out on the notarisation servers.

Sometimes it takes a few days for such fixes to bed in; if you continue to have problems by the time next week rolls around, please do let us know.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

That is correct. The workaround to thin binaries is no longer necessary and individual tickets will be generated for all slices of universal binaries. Tickets are being regenerated now for all affected uploads.

Thanks, Quinn. I can confirm it's now working here for AppleScript applets.

I can confirm it's now working here for AppleScript applets.

Yay!

Just FYI, we filed an internal bug for Script Editor to automatically create notarisable (is that a word?) apps when you export the app with signing enabled (r. 50573240).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

> Just FYI, we filed an internal bug for Script Editor to automatically create notarisable (is that a word?) apps when you export the app with signing enabled (r. 50573240).


And FYI, I've filed 50442691 and 50442399 on issues that prevent notarizing of apps saved from Automator.app.


We've also released a free app to simplify notarizing -- I'm not sure if it's etiquette to post a link here.

And FYI, I've filed 50442691 and 50442399 on issues that prevent notarizing of apps saved from Automator.app.

Thanks for that!

I'm not sure if it's etiquette to post a link here.

Generally not, but I’m happy to post a link (just so long as everyone agrees that it’s not considered an endorsement :-).

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

And FYI, I've filed 50442691 …

Oh, one tidbit about this bug: If you pass

--deep
to
codesign
, the notarisation should then succeed. Alternatively, and this is what I generally prefer, you can run
codesign
twice, once for
document.wflow
and again for the outer app.

And yes, I realise that it’s still not following the rules as per TN2206 )-:

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Quinn,


Thanks for the follow-up; DTS have replied similarly.


Can you comment further on the seeming conflict between what TN2206 says about using --deep and this suggestion? Is it more a matter of --deep shouldn't be relied on as a fix-all, but will cause no harm (and some good in odd cases like this).


I guess I'm asking if there's any harm in using --deep by default. Or would it be better to just separately sign every file found in Contents/?


The issue I'm getting at is that adding --deep fixes the issue with .wflow files not signing, but it also fixes the same issue with Script Debugger.plist files, which have also historically been saved in Contents/. (So, presumably, will signing the Script Debugger.plist files first.)


I'm searching for the best approach that fits as many situations as possible...

So using --deep or signing the .wflow first let me notarize successfully. But...

My normal workflow is to do the inside out signing, and then check the signature before continuing, using:

/usr/sbin/spctl --assess --type exec -vv /path/to/the.app

But when I do that, having used either of the above solutions, I get this:

15:05:56.124: Result for /usr/sbin/spctl --assess --type exec -vv /path/to/the.app
Termination status: 3
StandardOut: (null)
StandardError:path/to/the.app: rejected
source=Unnotarized Developer ID
origin=Developer ID Application: Shane Stanley (LT9SRJ2NCV)

And I see that codesign actually returned this error:

/usr/bin/codesign --force -o runtime --timestamp --entitlements /path/to/Entitlements.plist --verbose=4 -s Developer ID Application: Shane Stanley (LT9SRJ2NCV) /path/to/the.app
Developer ID Application: Shane Stanley (LT9SRJ2NCV): found in both /Users/shane/... and /Users/shane/Library/Keychains/login.keychain-db (this is all right)
/path/to/the.app: signed app bundle with Mach-O thin (x86_64) [com.apple.automator.Automator-test3]

So should I just not bother doing the spctl check, and ignore the error in codesign?


(That error is after the .wflow file was signed separately, but the result is the same when using deep.)

Can you comment further on the seeming conflict between what TN2206 says about using

--deep
and this suggestion?

Sure.

--deep
is a shortcut. It tells
codesign
to search for nested code and sign that exactly like the top-level code is signed. Sometimes that shortcut works just fine, but in some cases it fails. And some of those failures are horrible (like misidentifying nested code) and others are not a big deal (like applying entitlements to nested shared libraries; entitlements only make sense on executables and thus applying them to non-executable code is pointless and misleading, although not actively harmful).

Personally, I might use

--deep
for a quick hack but, if I’m setting up signing for a real product, I avoid it.

The issue I'm getting at is that adding

--deep
fixes … the same issue with
Script Debugger.plist
files, which have also historically been saved in
Contents/
.

I’d have to look at that specific issue in more depth before I can offer definitive advice.

And I see that

codesign
actually returned this error:

I don’t see an error there at all?

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

> I don’t see an error there at all?


The termination status is 0, but what I posted is output to standardOut -- but only if I use --deep or if I sign the .wflow file first. And when it is output, spctl follows up with a rejection.


I'm just wondering how it is that apps spctl rejects are successfully uploaded and notarized. Maybe I'm worrying over nothing, and should just skip the spctl check. But I'm surprised, and it's the first reference I've seen to "source=Unnotarized Developer ID".


PS: I realise I updated to 10.14.5 today. Could that be the source of what I'm seeing with spctl?

Just an update: yes, I think what I'm seeing is a result of moving to 10.14.5. Presumably my spctl test is now performing the test that Gatekeeper is now performing, which means it's going to fail (at least with a hardened runtime app) until an app has been notarized. Surprising, but it makes sense. The issue of --deep and/or signing the .wflow files appears to have been a red herring.

I am trying to follow same process.

Running on 10.14.5

After stapling .app file with this output:

The staple and validate action worked!


When I check the .app file:

MacBook-Pro:dmg raulsanchez$ spctl -a -t exec -vvv Time\ Doctor\ 2.app/
Time Doctor 2.app/: accepted
origin=Developer ID Application: R Rawson (XXXXXXX)


What am I missing? Could you help please?


Thanks

If the stapling worked, I don't see any problem there.

Hi, Quinn,


I'm currently seeing exactly the same problem, and saw that you said it should be fixed now... but I'm still seeing the error 65 here.


I'm going to try thinning the applet, as we have no need to run it on 32-bit systems, but if this is a bug and it's back, I thought you should be aware.

I don't know if this can be of any help to others but I got the same stapling "error 65" in the following case

  1. I created a DMG containing a classical bundle "myTest.app"
  2. I successfully notarized the .dmg file
  3. I got the "Error 65" when trying to staple it.
Processing: /Users/xxxx/Development/myTest_Install.dmg
CloudKit query for myTest_Install.dmg (2/aaf85e0a1c60c86705e9a8880ebe1ad4cd32bf56) failed due to "Record not found".
Could not find base64 encoded ticket in response for 2/aaf85e0a1c60c86705e9a8880ebe1ad4cd32bf56
The staple and validate action failed! Error 65.

I ultimately found was that the error was due "myTest.app" not being notarized !!!!

Come on Apple, instead of an error message that only aliens can understand it would not be too difficult to give us something more helpful!

All the best

Stapling Error 65 (Applescript app)
 
 
Q