Notarize Apple binaries
Apple notarization is a security process introduced by Apple for macOS and macOS-related software distributed outside of the Mac App Store. It is a mandatory step for all software built after June 1, 2019, and distributed with Developer ID, beginning in macOS 10.15.
Notarization aims to enhance the security of macOS by ensuring that all software distributed outside of the Mac App Store is checked for malicious content and conforms to Apple's security standards before being installed on users' devices.
DigiCert® Software Trust Manager simplifies the Apple notarization process by enabling you to notarize your Apple binaries with Signing Manager Controller (SMCTL), a command line interface (CLI).
Follow these instructions to notarize your Apple binaries with Signing Manager Controller (SMCTL) using notarytool.
Prerequisites
macOS
Nota
notarytool is provided as part of the macOS.
Xcode command Utility
Apple credentials for notarization
Create one of the following Apple credentials based on the notarization tool you want to use.
Save your Apple credentials to Keychain
Use the following one of the following commands to save your credentials to Keychain.
Dica
The profile name you give your credentials in Keychain will be used in notarization commands.
Notarize
Notarization produces a ticket that tells Gatekeeper that your app is notarized. After notarization completes, when a user attempts to run your app on macOS 10.14 or later, Gatekeeper will find the ticket online.
Nota
Before notarization, the binary must be:
Signed
Provided in one of the following formats:
.pkg
.dmg
.zip
(Compress .app binaries into a .zip)
The notarize command below will:
Notarize your binary.
Upload your binary to Apple notary Server (this may take a while).
Once uploaded, the notary server will provide you with the submission ID.
Dica
The submission ID is used to check the status and log of the notarization.
Notarization status
After you upload your file, the notarization process typically takes less than an hour. To check the status of the request, follow one of the procedures outlined below.
Nota
Notarization ID is the Software Trust Manager server notarization ID.
Submission ID is the NotaryServer ID provided after the file was successfully uploaded.
Notarization logs
The notary log is a key tool for debugging notarization and trusted execution issues. Check the notarization logs for information on why notarization failed, to check for warnings, and to confirm that all your code was included in the notarized ticket.
Nota
Notarization logs are only available in notarytool. Always check the log file, even if notarization succeeds, because it might contain warnings that you can fix prior to your next submission.
To check the logs created by Notary Server:
smctl-mac-x64 notarization log --tool notarytool <notarization ID or submission ID> --profile-name <Keychain credentials profile name> -v
Command sample:
smctl-mac-x64 notarization log --tool notarytool 5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03 --profile-name <Keychain credentials profile name> -v
Command output:
{ "logFormatVersion": 1, "jobId": "5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03", "status": "Accepted", "statusSummary": "Ready for distribution", "statusCode": 0, "archiveFilename": "example.dylib.dmg", "uploadDate": "2023-04-17T06:34:20.469Z", "sha256": "74c81b1fe123d994e56e153833896302d4d9398a6b0a3f3f5518e8b86393db6", "ticketContents": [ { "path": "example.dylib.dmg", "digestAlgorithm": "SHA-256", "cdhash": "5fa62fc5f5bec1f2b1464adc0d203393c0994cef" }, { "path": "example.dylib.dmg/example.dylib", "digestAlgorithm": "SHA-256", "cdhash": "76e7cbde3fb5434d015a22b4eccdea567e44a25b", "arch": "x86_64" } ], "issues": null } logsCommand command was SUCCESSFUL a7abfd6f-6367-443e-96a6-ab7dff751447 ID: a7abfd6f-6367-443e-96a6-ab7dff751447 SUBMISSION ID: 5ad03d00-8ab1-4fdc-bb0a-f4167dc01f03 SIGNATUREID: CREATED ON:2023-04-17 06:34:20 +0000 UTC CREATED BY:stm user MODIFIED ON:2023-04-17 06:37:27 +0000 UTC MODIFIED BY:stm user ACCOUNT ID:f28bd2a7-4762-1111-b40b-826ea4b1b3e4 LOG: Tool Used: notarytool Timestamp:2023-04-17 06:37:27.506724 +0000 UTC log: { "logFormatVersion": 1, "jobId": "5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03", "status": "Accepted", "statusSummary": "Ready for distribution", "statusCode": 0, "archiveFilename": "example.dylib.dmg", "uploadDate": "2023-04-17T06:34:20.469Z", "sha256": "40c81b1fe9528d994e56e153833896302d4d9398a6b0a3f3f5518e8b86393db6", "ticketContents": [ { "path": "example.dylib.dmg", "digestAlgorithm": "SHA-256", "cdhash": "5fa62fc5f5bec1f2b1464adc0d203393c0994cef" }, { "path": "example.dylib.dmg/example.dylib", "digestAlgorithm": "SHA-256", "cdhash": "76e7cbde3fb5434d015a22b4eccdea567e44a25b", "arch": "x86_64" } ], "issues": null } Tool Used: notarytool Timestamp:2023-04-17 06:36:34.874059 +0000 UTC log: {"status":"Accepted","id":"5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03","createdDate":"2023-04-17T06:34:17.574Z","message":"Successfully received submission info","name":"example.dylib.dmg"} Tool Used: notarytool Timestamp:2023-04-17 06:34:20.706515 +0000 UTC log: {"path":"\/Users\/john.doe\/Documents\/testing\/example.dylib.dmg","id":"5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03","message":"Successfully uploaded file"}
Staple
Staple to attach the ticket to your software using the stapler tool. This ensures that future distributions include the ticket and that Gatekeeper can find the ticket even when a network connection isn’t available.
Nota
Before stapling the ticket, binaries must be:
Signed
Notarized
Provided in one of the following formats:
.pkg
.dmg
.app
Use the .app binary that was compressed in the .zip file for notarization.
.zip is not supported in staple commands.
To staple the ticket created for the Notarization to the app:
smctl-mac-x64 notarization stapler <notarization ID or submission ID> -v --input <file_to_be_stapled>
Command sample:
smctl-mac-x64 notarization stapler 5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03 -v --input /Users/john.doe/Documents/testing/example.dylib.dmg
Command output:
Processing: /Users/john.doe/Documents/testing/example.dylib.dmg Properties are { NSURLIsDirectoryKey = 0; NSURLIsPackageKey = 0; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = "Disk Image"; NSURLTypeIdentifierKey = "com.apple.disk-image-udif"; "_NSURLIsApplicationKey" = 0; } Codesign offset 0x4675f8 length: 1702 Stored Codesign length: 1702 number of blobs: 1 Total Length: 1702 Found blobs: 1 Signing information is { cdhashes = ( {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef} ); "cdhashes-full" = { 2 = {length = 32, bytes = 0x5fa62fc5 f5bec1f2 b1464adc 0d203393 ... d2b1af9b b513d485 }; }; cms = {length = 0, bytes = 0x}; "digest-algorithm" = 2; "digest-algorithms" = ( 2 ); flags = 2; format = "disk image"; identifier = ADHOC; "main-executable" = "file:///Users/john.doe/Documents/testing/example.dylib.dmg"; source = "explicit detached"; unique = {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef}; } JSON Data is { records = ( { recordName = "2/2/5fa62fc5f5bec1f2b1464adc0d203393c0994cef"; } ); } Headers: { "Content-Type" = "application/json"; } Domain is api.apple-cloudkit.com Response is <NSHTTPURLResponse: 0x600003f98000> { 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 = ( "Mon, 17 Apr 2023 06:38:32 GMT" ); Server = ( "AppleHttpServer/3faf4ee9434b" ); "Strict-Transport-Security" = ( "max-age=31536000; includeSubDomains;" ); "Transfer-Encoding" = ( Identity ); Via = ( "xrail:st53p00ic-qujn13071302.me.com:8301:22R975:grp60,631194250daa17e24277dea86cf30319:6b81ca964848d4a99a95191d693d1b6c:inbom2" ); "X-Apple-CloudKit-Version" = ( "1.0" ); "X-Apple-Edge-Response-Time" = ( 202 ); "X-Apple-Request-UUID" = ( "4dccde07-bd07-43e8-bc0c-05730d18e7de" ); "X-Responding-Instance" = ( "ckdatabasews:16305401:st42p63ic-ztfb05112201:8807:2313B296:bbd264c3ef7e69b6ed64b5c2f5a1ba0167ac99d8" ); "access-control-expose-headers" = ( "X-Apple-Request-UUID,X-Responding-Instance,Via" ); "x-apple-user-partition" = ( 63 ); } } Size of data is 2845 JSON Response is: { records = ( { created = { deviceID = 2; timestamp = 1680684243226; userRecordName = "_b133e60953755a92966d7ca08d9c731a"; }; deleted = 0; fields = { signedTicket = { type = BYTES; value = "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"; }; }; modified = { deviceID = 2; timestamp = 1681713272266; userRecordName = "_b133e60953755a92966d7ca08d9c731a"; }; pluginFields = { }; recordChangeTag = lg3g05rh; recordName = "2/2/5fa62fc5f5bec1f2b1464adc0d203393c0994cef"; recordType = DeveloperIDTicket; } ); } Downloaded ticket has been stored at file:///var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/4dccde07-bd07-43e8-bc0c-05730d18e7de.ticket. Attempting to attach a new ticket to example.dylib.dmg. Let's see how that works out. Cloned /Users/john.doe/Documents/testing/example.dylib.dmg to /var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/TemporaryItems/NSIRD_stapler_AqeR1S/example.dylib.dmg Adding 1 blobs to superblob. What about Blob? Length of new ticket blob is 1682 A copy of the new disk image blobs and headers has been saved to /var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/C81805ED-D342-4A40-A289-EB5B6DAE3FF4-94768-00007880DD322E37.dmgData. Enjoy. Processing: /Users/john.doe/Documents/testing/example.dylib.dmg Properties are { NSURLIsDirectoryKey = 0; NSURLIsPackageKey = 0; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = "Disk Image"; NSURLTypeIdentifierKey = "com.apple.disk-image-udif"; "_NSURLIsApplicationKey" = 0; } Codesign offset 0x4675f8 length: 1702 Stored Codesign length: 1702 number of blobs: 1 Total Length: 1702 Found blobs: 1 Signing information is { cdhashes = ( {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef} ); "cdhashes-full" = { 2 = {length = 32, bytes = 0x5fa62fc5 f5bec1f2 b1464adc 0d203393 ... d2b1af9b b513d485 }; }; cms = {length = 0, bytes = 0x}; "digest-algorithm" = 2; "digest-algorithms" = ( 2 ); flags = 2; format = "disk image"; identifier = ADHOC; "main-executable" = "file:///Users/john.doe/Documents/testing/example.dylib.dmg"; source = "explicit detached"; unique = {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef}; } The staple and validate action worked! stapleCommand command for file /Users/john.doe/Documents/testing/example.dylib.dmg was SUCCESSFUL a7abfd6f-6367-443e-96a6-ab7dff751447
List notarizations
To list notarizations, run:
smctl-mac-x64 notarization ls
Command output:
ID SUBMISSION ID CREATED ON ACCOUNT ID SIGNATURE ID a7abfd6f-6367-443e-96a6-ab7dff751447 5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03 2023-04-17 06:34:20 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 fd8c9be9-d548-48e5-961b-9f3e1361c356 08a7c877-9e11-46d7-8936-a76398f44313 2023-04-17 06:35:13 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 e286e9c7-76b2-45ad-9c04-ad7ae171b5d7 2023-04-17 06:34:04 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 89ef3f9b-6528-4ff1-a7a0-227235ed5e15 2023-04-17 06:33:34 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 217f182c-6e08-4cc3-bb2f-8717dc0512a5 71daf9d8-403d-4884-9647-073c2c2d3de9 2023-04-17 06:26:53 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 8c60cd99-0d13-4c0e-9818-82251ae584fe fce8f59e-c1f3-4341-92ed-6014a0cb4ec4 2023-04-17 06:12:29 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 41fa58ed-c22b-450e-91f8-55a1568d4dc2 2023-04-17 06:24:22 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 e981f52c-0857-435c-afcf-228138fd05c2 2023-04-17 06:23:45 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 ca9c10ab-b2e5-48fc-abee-4b018a0b6779 2023-04-17 06:13:14 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 41fcf167-2ca7-4c84-aff1-eb664c5c7150 2f623367-7cba-4269-b391-e433f83d4e6c 2023-04-17 06:09:41 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4 b553418a-f77e-4fb2-81a2-8ddab656b3cc 35581022-e5a3-4361-9418-b2e1995f5cca 2023-04-17 06:08:29 +0000 UTC f28bd2a7-0183-4311-b40b-826ea4b1b3e4
Describe notarizations
To describe notarizations:
smctl-mac-x64 notarization describe <notarization ID>
Command sample:
smctl-mac-x64 notarization describe 5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03
Command output:
ID: a7abfd6f-6367-443e-96a6-ab7dff751447 SUBMISSION ID: 5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03 SIGNATUREID: CREATED ON:2023-04-17 06:34:20 +0000 UTC CREATED BY:stm user MODIFIED ON:2023-04-17 06:38:32 +0000 UTC MODIFIED BY:stm user ACCOUNT ID:f28bd2a7-0183-4311-b40b-826ea4b1b3e4 LOG: Tool Used: stapler Timestamp:2023-04-17 06:38:32.401508 +0000 UTC log: Processing: /Users/john.doe/Documents/testing/example.dylib.dmg Properties are { NSURLIsDirectoryKey = 0; NSURLIsPackageKey = 0; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = "Disk Image"; NSURLTypeIdentifierKey = "com.apple.disk-image-udif"; "_NSURLIsApplicationKey" = 0; } Codesign offset 0x4675f8 length: 1702 Stored Codesign length: 1702 number of blobs: 1 Total Length: 1702 Found blobs: 1 Signing information is { cdhashes = ( {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef} ); "cdhashes-full" = { 2 = {length = 32, bytes = 0x5fa62fc5 f5bec1f2 b1464adc 0d203393 ... d2b1af9b b513d485 }; }; cms = {length = 0, bytes = 0x}; "digest-algorithm" = 2; "digest-algorithms" = ( 2 ); flags = 2; format = "disk image"; identifier = ADHOC; "main-executable" = "file:///Users/John.Doe/Documents/testing/example.dylib.dmg"; source = "explicit detached"; unique = {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef}; } JSON Data is { records = ( { recordName = "2/2/5fa62fc5f5bec1f2b1464adc0d203393c0994cef"; } ); } Headers: { "Content-Type" = "application/json"; } Domain is api.apple-cloudkit.com Response is <NSHTTPURLResponse: 0x600003f98000> { 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 = ( "Mon, 17 Apr 2023 06:38:32 GMT" ); Server = ( "AppleHttpServer/3faf4ee9434b" ); "Strict-Transport-Security" = ( "max-age=31536000; includeSubDomains;" ); "Transfer-Encoding" = ( Identity ); Via = ( "xrail:st53p00ic-qujn13071302.me.com:8301:22R975:grp60,631194250daa17e24277dea86cf30319:6b81ca964848d4a99a95191d693d1b6c:inbom2" ); "X-Apple-CloudKit-Version" = ( "1.0" ); "X-Apple-Edge-Response-Time" = ( 202 ); "X-Apple-Request-UUID" = ( "4dccde07-bd07-43e8-bc0c-05730d18e7de" ); "X-Responding-Instance" = ( "ckdatabasews:16305401:st42p63ic-ztfb05112201:8807:2313B296:bbd264c3ef7e69b6ed64b5c2f5a1ba0167ac99d8" ); "access-control-expose-headers" = ( "X-Apple-Request-UUID,X-Responding-Instance,Via" ); "x-apple-user-partition" = ( 63 ); } } Size of data is 2845 JSON Response is: { records = ( { created = { deviceID = 2; timestamp = 1680684243226; userRecordName = "_b133e60953755a92966d7ca08d9c731a"; }; deleted = 0; fields = { signedTicket = { type = BYTES; value = "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"; }; }; modified = { deviceID = 2; timestamp = 1681713272266; userRecordName = "_b133e60953755a92966d7ca08d9c731a"; }; pluginFields = { }; recordChangeTag = lg3g05rh; recordName = "2/2/5fa62fc5f5bec1f2b1464adc0d203393c0994cef"; recordType = DeveloperIDTicket; } ); } Downloaded ticket has been stored at file:///var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/4dccde07-bd07-43e8-bc0c-05730d18e7de.ticket. Attempting to attach a new ticket to example.dylib.dmg. Let's see how that works out. Cloned /Users/john.doe/Documents/testing/example.dylib.dmg to /var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/TemporaryItems/NSIRD_stapler_AqeR1S/example.dylib.dmg Adding 1 blobs to superblob. What about Blob? Length of new ticket blob is 1682 A copy of the new disk image blobs and headers has been saved to /var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/C81805ED-D342-4A40-A289-EB5B6DAE3FF4-94768-00007880DD322E37.dmgData. Enjoy. Processing: /Users/john.doe/Documents/testing/example.dylib.dmg Properties are { NSURLIsDirectoryKey = 0; NSURLIsPackageKey = 0; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = "Disk Image"; NSURLTypeIdentifierKey = "com.apple.disk-image-udif"; "_NSURLIsApplicationKey" = 0; } Codesign offset 0x4675f8 length: 1702 Stored Codesign length: 1702 number of blobs: 1 Total Length: 1702 Found blobs: 1 Signing information is { cdhashes = ( {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef} ); "cdhashes-full" = { 2 = {length = 32, bytes = 0x5fa62fc5 f5bec1f2 b1464adc 0d203393 ... d2b1af9b b513d485 }; }; cms = {length = 0, bytes = 0x}; "digest-algorithm" = 2; "digest-algorithms" = ( 2 ); flags = 2; format = "disk image"; identifier = ADHOC; "main-executable" = "file:///Users/john.doe/Documents/testing/example.dylib.dmg"; source = "explicit detached"; unique = {length = 20, bytes = 0x5fa62fc5f5bec1f2b1464adc0d203393c0994cef}; } The staple and validate action worked! Tool Used: notarytool Timestamp:2023-04-17 06:37:27.506724 +0000 UTC log: { "logFormatVersion": 1, "jobId": "5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03", "status": "Accepted", "statusSummary": "Ready for distribution", "statusCode": 0, "archiveFilename": "example.dylib.dmg", "uploadDate": "2023-04-17T06:34:20.469Z", "sha256": "40c81b1fe9528d994e56e153833896302d4d9398a6b0a3f3f5518e8b86393db6", "ticketContents": [ { "path": "example.dylib.dmg", "digestAlgorithm": "SHA-256", "cdhash": "5fa62fc5f5bec1f2b1464adc0d203393c0994cef" }, { "path": "example.dylib.dmg/example.dylib", "digestAlgorithm": "SHA-256", "cdhash": "76e7cbde3fb5434d015a22b4eccdea567e44a25b", "arch": "x86_64" } ], "issues": null } Tool Used: notarytool Timestamp:2023-04-17 06:36:34.874059 +0000 UTC log: {"status":"Accepted","id":"5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03","createdDate":"2023-04-17T06:34:17.574Z","message":"Successfully received submission info","name":"example.dylib.dmg"} Tool Used: notarytool Timestamp:2023-04-17 06:34:20.706515 +0000 UTC log: {"path":"\/Users\/john.doe\/Documents\/testing\/example.dylib.dmg","id":"5cb03d00-8ab1-4fdc-bb0a-f4167dc01f03","message":"Successfully uploaded file"}
Verify notarization
To verify the stapler command, use the command:
smctl-mac-x64 notarization stapler verify -v --input <path to notarized path>
Command sample:
smctl-mac-x64 notarization stapler verify -v --input /Users/john.doe/Documents/testing/DigiCert\ example.app
Command output:
Processing: /Users/john.doe/Documents/testing/example.app Properties are { NSURLIsDirectoryKey = 1; NSURLIsPackageKey = 1; NSURLIsSymbolicLinkKey = 0; NSURLLocalizedTypeDescriptionKey = Application; NSURLTypeIdentifierKey = "com.apple.application-bundle"; "_NSURLIsApplicationKey" = 1; } Props are { cdhash = {length = 20, bytes = 0xb6073a31b4665e3e73a16f59d9ddfbc4e16912c6}; digestAlgorithm = 2; flags = 65536; secureTimestamp = "2023-03-09 14:25:26 +0000"; signingId = DigiCert; teamId = DESP6SPB3R; } JSON Data is { records = ( { recordName = "2/2/b6073a31b4665e3e73a16f59d9ddfbc4e16912c6"; } ); } Headers: { "Content-Type" = "application/json"; } Domain is api.apple-cloudkit.com Response is <NSHTTPURLResponse: 0x600002fbc0c0> { 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 = ( "Tue, 18 Apr 2023 05:46:40 GMT" ); Server = ( "AppleHttpServer/3faf4ee9434b" ); "Strict-Transport-Security" = ( "max-age=31536000; includeSubDomains;" ); "Transfer-Encoding" = ( Identity ); Via = ( "xrail:st53p00ic-qujn12061102.me.com:8301:22R975:grp60,631194250daa17e24277dea86cf30319:52127579245e6c50c59cfb57df69ab68:nlhfd1" ); "X-Apple-CloudKit-Version" = ( "1.0" ); "X-Apple-Edge-Response-Time" = ( 98 ); "X-Apple-Request-UUID" = ( "a2d569cd-58fc-4420-829d-988d54ea3504" ); "X-Responding-Instance" = ( "ckdatabasews:16308601:st42p63ic-ztfb18191901:8807:2313B296:bbd264c3ef7e69b6ed64b5c2f5a1ba0167ac99d8" ); "access-control-expose-headers" = ( "X-Apple-Request-UUID,X-Responding-Instance,Via" ); "x-apple-user-partition" = ( 63 ); } } Size of data is 2957 JSON Response is: { records = ( { created = { deviceID = 2; timestamp = 1678372170142; userRecordName = "_b133e60953755a92966d7ca08d9c731a"; }; deleted = 0; fields = { signedTicket = { type = BYTES; value = "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"; }; }; modified = { deviceID = 2; timestamp = 1681796391198; userRecordName = "_b133e60953755a92966d7ca08d9c731a"; }; pluginFields = { }; recordChangeTag = lf17geql; recordName = "2/2/b6073a31b4665e3e73a16f59d9ddfbc4e16912c6"; recordType = DeveloperIDTicket; } ); } Downloaded ticket has been stored at file:///var/folders/x1/_4323gz167n633s877chh3_c0000gq/T/a2d569cd-58fc-4420-829d-988d54ea3504.ticket. The validate action worked!verifyStaplerCommand command for file /Users/john.doe/Documents/testing/example.app was SUCCESSFUL