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.
Stapler commands begin with:
smctl-mac-x64 notarization stapler <notarization ID or submission ID> <flags>
Stapler commands support these flags:
Shortcut | Flag | Description |
---|---|---|
--input string | Path to file. | |
-v | --verbose | Enable verbose logging for saving credentials. |
-h | --help | Help for describing a scan. |
Description: Staple the ticket created for the Notarization to the app.
Command:
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
Output sample:
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/smpkcs11.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
For help with the describe scan command, use:
smctl-mac-x64 notarization stapler --help
Alternatively, use the abbreviated version of the command:
smctl-mac-x64 notarization stapler -h