diff --git a/package.json b/package.json
index bd05b090df..0836f624d2 100644
--- a/package.json
+++ b/package.json
@@ -111,6 +111,7 @@
     "electron-builder": "^21.2.0",
     "electron-builder-squirrel-windows": "^21.2.0",
     "electron-devtools-installer": "^2.2.4",
+    "electron-notarize": "^0.1.1",
     "eslint": "^5.8.0",
     "eslint-config-google": "^0.7.1",
     "eslint-plugin-babel": "^4.1.2",
@@ -188,6 +189,7 @@
       "buildResources": "electron_app/build",
       "output": "electron_app/dist",
       "app": "electron_app"
-    }
+    },
+    "afterSign": "scripts/electron_afterSign.js"
   }
 }
diff --git a/scripts/electron-package.sh b/scripts/electron-package.sh
index 63c2fd72d7..9b796b9546 100755
--- a/scripts/electron-package.sh
+++ b/scripts/electron-package.sh
@@ -67,6 +67,14 @@ if [ ! -f package.json ]; then
     exit
 fi
 
+if [ -z "$NOTARIZE_APPLE_ID" ]; then
+    echo "NOTARIZE_APPLE_ID is not set"
+    exit
+fi
+
+# Test that altool can get its credentials for notarising the mac app
+xcrun altool -u "$NOTARIZE_APPLE_ID" -p '@keychain:NOTARIZE_CREDS' --list-apps || exit
+
 echo "Building $version using Update base URL $update_base_url"
 
 projdir=`pwd`
diff --git a/scripts/electron_afterSign.js b/scripts/electron_afterSign.js
new file mode 100644
index 0000000000..0d42c55246
--- /dev/null
+++ b/scripts/electron_afterSign.js
@@ -0,0 +1,26 @@
+const { notarize } = require('electron-notarize');
+
+exports.default = async function(context) {
+    const { electronPlatformName, appOutDir } = context;
+    if (electronPlatformName !== 'darwin') {
+        return;
+    }
+
+    // We get the password from keychain. The keychain stores
+    // user IDs too, but apparently altool can't get the user ID
+    // from the keychain, so we need to get it from the environment.
+    const userId = process.env.NOTARIZE_APPLE_ID;
+    if (userId === undefined) {
+        throw new Exception("User ID not found. Set NOTARIZE_APPLE_ID.");
+    }
+
+    const appName = context.packager.appInfo.productFilename;
+
+    console.log("Notarising macOS app. This may be some time.");
+    return await notarize({
+        appBundleId: 'im.riot.app',
+        appPath: `${appOutDir}/${appName}.app`,
+        appleId: userId,
+        appleIdPassword: '@keychain:NOTARIZE_CREDS',
+    });
+};
diff --git a/yarn.lock b/yarn.lock
index b1eb8246f8..c3cb2a7a77 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3134,6 +3134,14 @@ electron-devtools-installer@^2.2.4:
     rimraf "^2.5.2"
     semver "^5.3.0"
 
+electron-notarize@^0.1.1:
+  version "0.1.1"
+  resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-0.1.1.tgz#c3563d70c5e7b3315f44e8495b30050a8c408b91"
+  integrity sha512-TpKfJcz4LXl5jiGvZTs5fbEx+wUFXV5u8voeG5WCHWfY/cdgdD8lDZIZRqLVOtR3VO+drgJ9aiSHIO9TYn/fKg==
+  dependencies:
+    debug "^4.1.1"
+    fs-extra "^8.0.1"
+
 electron-publish@21.2.0:
   version "21.2.0"
   resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-21.2.0.tgz#cc225cb46aa62e74b899f2f7299b396c9802387d"
@@ -4083,7 +4091,7 @@ fs-extra@^0.30.0:
     path-is-absolute "^1.0.0"
     rimraf "^2.2.8"
 
-fs-extra@^8.1.0:
+fs-extra@^8.0.1, fs-extra@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0"
   integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==