Issues with Notarization and Stapling

Hello, I am trying without luck to create a .dmg or .pkg for my electron app that can be opened by any user on a mac. Every time I fail. All is happening by the same pattern. Here is the last try with creating a .pkg instead of .dmg.

  1. The app is built and it is signed correctly (I suppose)
codesign --verify --verbose=1 dist/mac-universal/VIVIDTIME.app
dist/mac-universal/VIVIDTIME.app: valid on disk
dist/mac-universal/VIVIDTIME.app: satisfies its Designated Requirement
  1. I created a .pkg
pkgbuild --root "dist/mac-universal/VIVIDTIME.app" \
  --install-location "/Applications/VIVIDTIME.app" \
  --identifier "app.vividtime.mac" \
  --version "1.1.0" \
  --sign "Developer ID Installer: Pavel Bochkov-Rastopchin (2QKDCTR5Y3)" \
  dist/VIVIDTIME.pkg
pkgbuild: Inferring bundle components from contents of dist/mac-universal/VIVIDTIME.app
pkgbuild: Adding component at Contents/Frameworks/Mantle.framework
pkgbuild: Adding component at Contents/Frameworks/VIVIDTIME Helper.app
pkgbuild: Adding component at Contents/Frameworks/VIVIDTIME Helper (GPU).app
pkgbuild: Adding component at Contents/Frameworks/Electron Framework.framework
pkgbuild: Adding component at Contents/Frameworks/Squirrel.framework
pkgbuild: Adding component at Contents/Frameworks/VIVIDTIME Helper (Renderer).app
pkgbuild: Adding component at Contents/Frameworks/VIVIDTIME Helper (Plugin).app
pkgbuild: Adding component at Contents/Frameworks/ReactiveObjC.framework
pkgbuild: Using timestamp authority for signature
pkgbuild: Signing package with identity "Developer ID Installer: Pavel Bochkov-Rastopchin (2QKDCTR5Y3)" from keychain /Users/innrvoice/Library/Keychains/login.keychain-db
pkgbuild: Adding certificate "Developer ID Certification Authority"
pkgbuild: Adding certificate "Apple Root CA"
pkgbuild: Wrote package to dist/VIVIDTIME.pkg
Answered by ForumsContributor in
  1. I checked the .pkg and everything seems to be ok.

pkgutil --check-signature dist/VIVIDTIME.pkg

Package "VIVIDTIME.pkg":

   Status: signed by a developer certificate issued by Apple for distribution

   Signed with a trusted timestamp on: 2025-02-18 14:59:40 +0000

   Certificate Chain:

    1. Developer ID Installer: Pavel Bochkov-Rastopchin (2QKDCTR5Y3)

       Expires: 2027-02-01 22:12:15 +0000

       SHA256 Fingerprint:

        .....

       ------------------------------------------------------------------------

    2. Developer ID Certification Authority

       Expires: 2027-02-01 22:12:15 +0000

       SHA256 Fingerprint:

          ...

       ------------------------------------------------------------------------

    3. Apple Root CA

       Expires: 2035-02-09 21:40:36 +0000

       SHA256 Fingerprint:

          ....

  1. I notarized the .pkg



xcrun notarytool submit "dist/VIVIDTIME.pkg" \



  --apple-id "p.bochkov.rastopchin@icloud.com" \



  --password "**************" \



  --team-id "2QKDCTR5Y3" \



  --wait



Conducting pre-submission checks for VIVIDTIME.pkg and initiating connection to the Apple notary service...



Submission ID received



  id: 8c5e3bbf-2938-4ea6-a568-a816a5b0af76



Upload progress: 100,00 % (201 MB of 201 MB)   



Successfully uploaded file



  id: 8c5e3bbf-2938-4ea6-a568-a816a5b0af76



  path: /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg



Waiting for processing to complete.



Current status: Accepted................



Processing complete



  id: 8c5e3bbf-2938-4ea6-a568-a816a5b0af76



  status: Accepted



  1. I checked the notarization



xcrun notarytool log 8c5e3bbf-2938-4ea6-a568-a816a5b0af76 \



  --apple-id "p.bochkov.rastopchin@icloud.com" \



  --password "****************" \



  --team-id "2QKDCTR5Y3"



{



  "logFormatVersion": 1,



  "jobId": "8c5e3bbf-2938-4ea6-a568-a816a5b0af76",



  "status": "Accepted",



  "statusSummary": "Ready for distribution",



  "statusCode": 0,



  "archiveFilename": "VIVIDTIME.pkg",



  "uploadDate": "2025-02-18T15:02:34.542Z",



  "sha256": "d0b2a066555c49f032540aa3bd87852eb106395b8d685097594daef66f52ee53",



  "ticketContents": [



    {



      "path": "VIVIDTIME.pkg/VIVIDTIME.pkg Contents/Payload/Applications/VIVIDTIME.app/Contents/Frameworks/VIVIDTIME Helper (Plugin).app",



      "digestAlgorithm": "SHA-256",



      "cdhash": "7d872ce50e0fe4fdbf77910c19a8582f3ec0dc8c",



      "arch": "x86_64"



    },



 ... some info skipped...,



    {



      "path": "VIVIDTIME.pkg",



      "digestAlgorithm": "SHA-1",



      "cdhash": "e5df4a77845f8a931674280e3b1bfd9e86c6004b"



    }



  ],



  "issues": null



}



  1. I try to staple the .pkg



xcrun stapler staple "dist/VIVIDTIME.pkg"



Processing: /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg



Could not validate ticket for /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg



The staple and validate action failed! Error 65.



Thats it. It is always like this whether I try to create a .dmg or .pkg. I tried rebuilding the app, resigning the .app, attaching the notarization ticket manually. Nothing works.

And more to that. Here is what I see when I try to simulate the Gatekeeper verification:




spctl --assess --type install --verbose=4 dist/VIVIDTIME.pkg



dist/VIVIDTIME.pkg: rejected



source=Unnotarized Developer ID



Could anyone please help me?

I am sorry for a post in multiple messages. Was trying to overcome the "sensitive information" warning in this long post by posting in parts =(

Hmmm, AFAICT you’re doing everything correctly here.

Two things:

  • Before you staple, run this command:

    % shasum -a 256 "dist/VIVIDTIME.pkg"
    

    The checksum should match the checksum in this your notary log:

    "sha256": "d0b2a066555c49f032540aa3bd87852eb106395b8d685097594daef66f52ee53",
    
  • In this command:

    % xcrun stapler staple "dist/VIVIDTIME.pkg"
    

    add a -v option and see what you get back. stapler should be looking for a ticket for the cdhash of your installer package, as reported in your notary log:

    "path": "VIVIDTIME.pkg",
    "digestAlgorithm": "SHA-1",
    "cdhash": "e5df4a77845f8a931674280e3b1bfd9e86c6004b"
    

    It’ll be interesting to see if that’s the case.

Share and Enjoy

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

Thank you very much for response.

Here is the current response from shasum:

shasum -a 256 "dist/VIVIDTIME.pkg"

d0b2a066555c49f032540aa3bd87852eb106395b8d685097594daef66f52ee53  dist/VIVIDTIME.pkg
  1. and here is what I get with -v:

xcrun stapler staple -v "dist/VIVIDTIME.pkg"

Processing: /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg

Properties are {

    NSURLIsDirectoryKey = 0;

    NSURLIsPackageKey = 0;

    NSURLIsSymbolicLinkKey = 0;

    NSURLLocalizedTypeDescriptionKey = "Installer flat package";

    NSURLTypeIdentifierKey = "com.apple.installer-package-archive";

    "_NSURLIsApplicationKey" = 0;

}

Sig Type is RSA. Length is 3

Sig Type is CMS. Length is 3

Package VIVIDTIME.pkg uses a checksum of size 20

JSON Data is {

    records =     (

                {

            recordName = "2/1/e5df4a77845f8a931674280e3b1bfd9e86c6004b";

        }

    );

}

 Headers: {

    "Content-Type" = "application/json";

}

Domain is api.apple-cloudkit.com

Response is <NSHTTPURLResponse: 0x14da041c0> { URL: https://api.apple-cloudkit.com/database/1/com.apple.gk.ticket-delivery/production/public/records/lookup } { Status Code: 200, Headers {

    Connection =     (

        "keep-alive"

    );

    "Content-Encoding" =     (

        gzip

    );

    "Content-Type" =     (

        "application/json; charset=UTF-8"

    );

    Date =     (

        "Wed, 19 Feb 2025 14:21:16 GMT"

    );

    Server =     (

        "AppleHttpServer/d2dcc6a0a5e3"

    );

    "Strict-Transport-Security" =     (

        "max-age=31536000; includeSubDomains;"

    );

    "Transfer-Encoding" =     (

        Identity

    );

   
Via =     (
        "xrail:LONG VALUE HERE"
    );

    "X-Apple-CloudKit-Version" =     (
        "1.0"
    );

    "X-Apple-Edge-Response-Time" =     (
        104
    );

    "X-Apple-Request-UUID" =     (
        "f1a6400c-7e79-423d-9638-d20092132813"
   );

    "X-Responding-Instance" =     (
        **"ckdatabasews:LONG VALUE HERE"**
    );
   "access-control-expose-headers" =     (
        "X-Apple-Request-UUID,X-Responding-Instance,Via"
    );
    "x-apple-user-partition" =     (
        63
    );
} }

Size of data is 3657


JSON Response is: {

records =     (

            {

        created =             {

            deviceID = 2;

            timestamp = 1739891....;

            userRecordName = "SOME SAME VALUE HERE.";

        };

 
   deleted = 0;
        fields =             {
            signedTicket =                 {
               type = BYTES;
                value = "VERY LONG VALUE HERE";
            };
        };
       
modified =             {
                deviceID = 2;
                timestamp = ...;
                userRecordName = "SOME SENSITIVE VALUE HERE";
            };
            pluginFields =             {
            };
            recordChangeTag = ....;
            recordName = ".....";
            recordType = DeveloperIDTicket;
        }
    );
}

Downloaded ticket has been stored at file:///var/folders/c3/622zwf656yz6h_v79t4_h8k40000gn/T/f1a6400c-7e79-423d-9638-d20092132813.ticket.

Could not validate ticket for /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg

The staple and validate action failed! Error 65.



I am again sorry for multiple posts. It is very hard to search for WHAT exactly is SENSITIVE information in a post, because all you see is a general warning.

and I see that cdhash you mentioned is present in stapler staple -v result here:

JSON Data is {
    records =     (
                {
            recordName = "2/1/e5df4a77845f8a931674280e3b1bfd9e86c6004b";
        }
    );
}
Written by innrvoice in 825675022
I am again sorry for multiple posts.

My general recommendation is that you post logs like this as text attachments, rather than separate code blocks. Did you try that and hit the same roadblock?

I’ve assembled all the bits you posted into such a file and attached it here. Mostly this is just to preserve my own sanity (-:

shasum -a 256 "dist/VIVIDTIME.pkg"

d0b2a066555c49f032540aa3bd87852eb106395b8d685097594daef66f52ee53  dist/VIVIDTIME.pkg

---------------------------------------------------------------------------

xcrun stapler staple -v "dist/VIVIDTIME.pkg"

Processing: /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg

Properties are {

    NSURLIsDirectoryKey = 0;

    NSURLIsPackageKey = 0;

    NSURLIsSymbolicLinkKey = 0;

    NSURLLocalizedTypeDescriptionKey = "Installer flat package";

    NSURLTypeIdentifierKey = "com.apple.installer-package-archive";

    "_NSURLIsApplicationKey" = 0;

}

Sig Type is RSA. Length is 3

Sig Type is CMS. Length is 3

Package VIVIDTIME.pkg uses a checksum of size 20

JSON Data is {

    records =     (

                {

            recordName = "2/1/e5df4a77845f8a931674280e3b1bfd9e86c6004b";

        }

    );

}

 Headers: {

    "Content-Type" = "application/json";

}

Domain is api.apple-cloudkit.com

Response is  { URL: https://api.apple-cloudkit.com/database/1/com.apple.gk.ticket-delivery/production/public/records/lookup } { Status Code: 200, Headers {

    Connection =     (

        "keep-alive"

    );

    "Content-Encoding" =     (

        gzip

    );

    "Content-Type" =     (

        "application/json; charset=UTF-8"

    );

    Date =     (

        "Wed, 19 Feb 2025 14:21:16 GMT"

    );

    Server =     (

        "AppleHttpServer/d2dcc6a0a5e3"

    );

    "Strict-Transport-Security" =     (

        "max-age=31536000; includeSubDomains;"

    );

    "Transfer-Encoding" =     (

        Identity

    );

Via =     (
        "xrail:LONG VALUE HERE"
    );

    "X-Apple-CloudKit-Version" =     (
        "1.0"
    );

    "X-Apple-Edge-Response-Time" =     (
        104
    );

    "X-Apple-Request-UUID" =     (
        "f1a6400c-7e79-423d-9638-d20092132813"
   );

    "X-Responding-Instance" =     (
        **"ckdatabasews:LONG VALUE HERE"**
    );
    
 "access-control-expose-headers" =     (
        "X-Apple-Request-UUID,X-Responding-Instance,Via"
    );
    "x-apple-user-partition" =     (
        63
    );
} }

Size of data is 3657

records =     (

            {

        created =             {

            deviceID = 2;

            timestamp = 1739891....;

            userRecordName = "SOME SAME VALUE HERE.";

        };
        
  deleted = 0;
        fields =             {
            signedTicket =                 {
               type = BYTES;
                value = "VERY LONG VALUE HERE";
            };
        };
       
modified =             {
                deviceID = 2;
                timestamp = ...;
                userRecordName = "SOME SENSITIVE VALUE HERE";
            };
            pluginFields =             {
            };
            recordChangeTag = ....;
            recordName = ".....";
            recordType = DeveloperIDTicket;
        }
    );
}

Downloaded ticket has been stored at file:///var/folders/c3/622zwf656yz6h_v79t4_h8k40000gn/T/f1a6400c-7e79-423d-9638-d20092132813.ticket.

Could not validate ticket for /Users/innrvoice/Documents/GitHub/vividtime-macos/app/electron/dist/VIVIDTIME.pkg

The staple and validate action failed! Error 65.

---------------------------------------------------------------------------

JSON Data is {
    records =     (
                {
            recordName = "2/1/e5df4a77845f8a931674280e3b1bfd9e86c6004b";
        }
    );
}

Note The fact that I can post this doesn’t tell you much, but not all forums contributors have the same privileges.

I’ll have more to say on the technical side in a bit.

Share and Enjoy

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

Issues with Notarization and Stapling
 
 
Q