-
-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Work out how to notarize the macOS application #50
Comments
Fantastic clues in this comment by @nikvdp
|
Nik's entitlements file: https://github.com/nikvdp/datasette.app/blob/fe75729e45f91f32c85f547c477bc19a48387fbb/build/entitlements.mac.plist And |
Via https://apple.stackexchange.com/a/52680 I learned the
electron-userland/electron-builder#3940 is interesting, including some debate over whether |
I saved the following to <?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>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.debugger</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist> And ran The build succeeded - but I'm worried that I didn't set Testing the build is annoying - you have to apparently upload it and download it again, or AirDrop it to yourself! https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html#//apple_ref/doc/uid/TP40005929-CH4-SW26 |
Instead I did:
Then uploaded that zip to an S3 bucket, downloaded it over HTTPS, unzipped it and opened the app. It opened without any warnings! Also, the entitlements seem to have stuck:
Next step: see if I can run that in CI. |
Based on https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/ I ran I added this as /* Based on https://kilianvalkhof.com/2019/electron/notarizing-your-electron-application/ */
const { notarize } = require("electron-notarize");
exports.default = async function notarizing(context) {
const { electronPlatformName, appOutDir } = context;
if (electronPlatformName !== "darwin") {
return;
}
const appName = context.packager.appInfo.productFilename;
return await notarize({
appBundleId: "io.datasette.app",
appPath: `${appOutDir}/${appName}.app`,
appleId: process.env.APPLEID,
appleIdPassword: process.env.APPLEIDPASS,
});
}; Then I ran this:
Got this error:
|
https://developer.apple.com/forums/thread/118045 showed me to run this:
|
This time a different error:
With wrapping:
|
https://support.apple.com/en-us/HT204397 describes app-specific passwords:
I went there and created an app-specific password called "Notarize Apps" which I saved in the 1Password entry for "[email protected] AppleID". |
OK, running this again, this time using that new app-specific password for the
This time it uploaded to Apple! And then failed, but it gave me an actionable log:
Here's that log file: {
"logFormatVersion": 1,
"jobId": "3f934ed8-c56f-4ddd-8ee5-f75bf137dc42",
"status": "Invalid",
"statusSummary": "Archive contains critical validation errors",
"statusCode": 4000,
"archiveFilename": "Datasette.zip",
"uploadDate": "2021-09-03T21:59:31Z",
"sha256": "170675a919d7ba2396d933a74190a04cc5fe33a68a97cc40c909028150397d3d",
"ticketContents": null,
"issues": [
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/bin/python3.9",
"message": "The binary is not signed.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/bin/python3.9",
"message": "The signature does not include a secure timestamp.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/bin/python3.9",
"message": "The executable does not have the hardened runtime enabled.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/xxlimited.cpython-39-darwin.so",
"message": "The binary is not signed.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/xxlimited.cpython-39-darwin.so",
"message": "The signature does not include a secure timestamp.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/_testcapi.cpython-39-darwin.so",
"message": "The binary is not signed.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/_testcapi.cpython-39-darwin.so",
"message": "The signature does not include a secure timestamp.",
"docUrl": null,
"architecture": "x86_64"
}
]
} |
This thread is useful: electron-userland/electron-builder#4656 https://www.electron.build/configuration/mac describes Here's an example of the
|
I think I need these two:
|
My "build": {
"appId": "io.datasette.app",
"mac": {
"category": "public.app-category.developer-tools",
"hardenedRuntime" : true,
"gatekeeperAssess": false,
"entitlements": "build/entitlements.mac.plist",
"entitlementsInherit": "build/entitlements.mac.plist",
"binaries": [
"./dist/mac/Datasette.app/Contents/Resources/python/bin/python3.9",
"./dist/mac/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/xxlimited.cpython-39-darwin.so"
]
},
"afterSign": "scripts/notarize.js",
"extraResources": [
{
"from": "python",
"to": "python",
"filter": [
"**/*"
]
}
]
}, |
{
"logFormatVersion": 1,
"jobId": "7dabec1f-b669-4912-8cc7-c022a51b6cdb",
"status": "Invalid",
"statusSummary": "Archive contains critical validation errors",
"statusCode": 4000,
"archiveFilename": "Datasette.zip",
"uploadDate": "2021-09-03T22:14:47Z",
"sha256": "d2785b0114a222d1985b362e663b6c8d71b86e429db1c90bc8daac5994ecd32f",
"ticketContents": null,
"issues": [
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/_testcapi.cpython-39-darwin.so",
"message": "The binary is not signed.",
"docUrl": null,
"architecture": "x86_64"
},
{
"severity": "error",
"code": null,
"path": "Datasette.zip/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/_testcapi.cpython-39-darwin.so",
"message": "The signature does not include a secure timestamp.",
"docUrl": null,
"architecture": "x86_64"
}
]
} I have a hunch this is going to be a series of whack-a-mole steps. |
I wonder if I'll need to sign everything in that folder that shows up as having executable permissions?
|
... that seemed to work that time? With the following binaries: "binaries": [
"./dist/mac/Datasette.app/Contents/Resources/python/bin/python3.9",
"./dist/mac/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/xxlimited.cpython-39-darwin.so",
"./dist/mac/Datasette.app/Contents/Resources/python/lib/python3.9/lib-dynload/_testcapi.cpython-39-darwin.so"
] I'll upload it and download it to test it. |
I added |
After downloading and unzipping it I ran the app - it got as far as the loading screen but hung there. The Lines 86 to 107 in b5d2d0c
|
Hunch: the permissions are not being inherited by the child |
Tried adding this entitlement:
|
OK, this time the app installed and ran for the first time and managed to install the stuff it needs in its But... attempting to open both CSV and DB files failed. Not sure why. |
Found some clues in the
Also spotted this:
And:
No idea what this one is about:
|
I've been running this all from |
No, same exact result. The app loads OK (and installs its virtual environment) but the open CSV menu option silently fails, without writing anything to the Console app either. |
I'll test installing from the latest artifact: https://github.com/simonw/datasette-app/actions/runs/1199643947 |
This time I got the following dialog on first launch, which is most excellent! The app successfully installed its virtual environment and ran. Still no luck opening a file though. I'm going to try and fix the following errors, even though they don't look like they relate to the ability to open files:
I'll try fixing the |
I really don't understand why I would want 'com.apple.security.personal-information.calendars': https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_personal-information_calendars
|
Unsurprisingly the |
Here's a guess at the problem: I have the But... that's not what the Electron app does. It instead takes that file path and does this with it: Lines 316 to 322 in 87038b4
Then the Python process running that web server attempts to read the file itself. My guess is that the Python process isn't inheriting the ability to open the file - and is then crashing without a useful error message. |
I can hack on |
Turns out the bug was that the CSV file I was trying to open had an error (see simonw/datasette-app-support#3) but I hadn't yet applied that fix in The app I installed from the latest build worked! It looks like it is successfully notarized. |
Turned this all into a TIL: https://til.simonwillison.net/electron/sign-notarize-electron-macos |
Split from #45 (I have a working certificate for signing now) and part of #20.
The text was updated successfully, but these errors were encountered: