Skip to main content

Signing Releases

Normally, we build artifacts via GitHub Actions as zip files, which can then be signed offline. This is necessary as the relevant certificates are not available online during CI.

In general, the process involves:

  1. Download the zip archive from GitHub.

    Note The archive will be a zip within a zip. Extract one level to get the file as generated by electron-builder.

  2. Set up the signing environment; see the platform-specific sections below.

  3. Run the signing tool:

    yarn sign path/to/archive.zip
  4. Look in dist/ for the signed files (Sulla.Desktop.Setup.msi, etc.).

Windows

On Windows, it is necessary to obtain a code signing certificate that can be used with the Windows infrastructure. It is then necessary to determine the fingerprint of the certificate, and set it as the CSC_FINGERPRINT environment variable before running yarn sign.

Generate a Test Certificate

For testing purposes, we can generate a certificate locally by running the following command in PowerShell:

New-SelfSignedCertificate `
-Type Custom `
-Subject "CN=Sulla-Desktop, C=CA" `
-KeyUsage DigitalSignature `
-CertStoreLocation Cert:\CurrentUser\My `
-FriendlyName "Sulla-Desktop Code Signing" `
-TextExtension @("2.5.29.37={text}1.3.6.1.5.5.7.3.3", "2.5.29.19={text}")

This will display the new certificate, with a Thumbprint column; this is the certificate fingerprint that we will need to set as CSC_FINGERPRINT. If you need to refer to the certificate later, it can be obtained by running ls Cert:\CurrentUser\My in a PowerShell prompt.

Using a Certificate Stored on a YubiKey

If you have a certificate (with private key) that is stored on a YubiKey device, it is first necessary to install the YubiKey Minidriver. After plugging in your device, you should then be able to run certutil -scinfo -silent to locate the fingerprint for your desired certificate. Note that this will list all the certificates on the device, including the chain to your certificate, and you must search the output for your signing certificate and locate the Cert Hash(sha1): entry. That hash is then used for CSC_FINGERPRINT above.

Verifying the Signed Product

In explorer, right-click on the final .exe file, choose Properties, Digital Signatures, and verify that Sulla AI is listed in the Signature List.

macOS

On macOS, a signing certificate from Apple is required (via their developer program). Please refer to Apple Documentation for details. Note that a Mac Development certificate is insufficient for notarization; it must be a Developer ID Application certificate. This will be reflected in the Common Name of the certificate.

Launch constraints require macOS Ventura (macOS 13) or newer. This is therefore needed for production signing.

Generate a test certificate

If a real certificate from Apple is unavailable, it is possible to generate a self-signed test certificate; however, note that this wouldn't properly exercise all of the signing code.

openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \
-keyform pem -sha256 -days 3650 -nodes -subj \
"/C=XX/ST=NA/L=Some Town/O=No Org/OU=No Unit/CN=RD Test Signing Key" \
-addext keyUsage=critical,digitalSignature \
-addext extendedKeyUsage=critical,codeSigning
security import key.pem -t priv -A
security import cert.pem -t cert -A
security set-key-partition-list -S apple-tool:,apple:,codesign: -s
security add-trusted-cert -p codeSign cert.pem

Configuring Access

  • Import your signing certificate into your macOS Keychain.
  • Run security find-identity -v to locate the fingerprint of the key to use. Export the long hex string as the CSC_FINGERPRINT environment variable.
    • For a test certificate, use security find-identity without -v; the certificate to use isn't valid.

For notarization, the following environment variables are also needed:

  • APPLEID
    • This is your Apple ID login; for example, john.doe@example.com
  • AC_PASSWORD
    • This is an application-specific password for your Apple ID; to create it:
      1. Navigate to https://appleid.apple.com/account/manage
      2. Click on App-Specific Passwords at the bottom.
      3. Create one (with a label of your choice) and copy the resulting password.
  • AC_TEAMID
    • This is the Apple Team ID. This is the Organizational Unit (OU) field of the subject of your signing certificate; for Sulla Desktop, this should match your Apple Developer Team ID. (This value can be extracted from the published application.)

Performing signing

When signing for M1/aarch64, please set the M1 environment variable ahead of time as usual.

If notarization is not required, append --skip-notarize to the command:

yarn sign --skip-notarize path/to/archive.zip

This is necessary to test the signing flow (since there's no way to notarize without the production certificate). This is also necessary to use a test certificate (since Apple will reject it).

When using an older version of macOS (12/Monterey or older), --skip-constraints is also needed to skip assigning launch constraints, as that requires Ventura or later. This is inappropriate for the actual release.