diff --git a/.github/workflows/update-windows-info.yml b/.github/workflows/update-windows-info.yml
new file mode 100644
index 0000000..55ee542
--- /dev/null
+++ b/.github/workflows/update-windows-info.yml
@@ -0,0 +1,104 @@
+name: Updates verify-installers.md after desktop release
+
+on:
+ repository_dispatch:
+ types: [desktop-release]
+
+defaults:
+ run:
+ shell: bash
+
+
+jobs:
+ create-pr:
+ name: Create PR to update windows signing cert
+ runs-on: windows-latest
+ permissions:
+ contents: write
+ env:
+ DESKTOP_VERSION: ${{ github.event.client_payload.version }}
+ steps:
+ - name: Checkout repo
+ uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Create new branch
+ run: |
+ git config --global --add safe.directory "$GITHUB_WORKSPACE"
+ if [[ ! "$DESKTOP_VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z]+)*$ ]]; then
+ echo "Invalid version in payload: $DESKTOP_VERSION" >&2
+ exit 1;
+ fi
+ git checkout -b "feature/desktop-${DESKTOP_VERSION}"
+ - name: Download MSI
+ run: |
+ MSI_URL=$(jq -r '[.[] | select(.name | endswith(".msi"))][0].browser_download_url // "null"' <<< "$ASSETS_JSON")
+ if [[ "$MSI_URL" == "null" || -z "$MSI_URL" ]]; then
+ echo "No MSI asset found in repository_dispatch payload." >&2
+ exit 1
+ fi
+ curl --silent --fail-with-body --proto "=https" -L -H "Accept: application/vnd.github+json" $MSI_URL --output cryptomator.msi
+ env:
+ ASSETS_JSON: ${{ toJson(github.event.client_payload.release.assets ) }}
+ - name: Update verify-installers.md
+ shell: pwsh
+ run: |
+ $Thumbprint = (Get-AuthenticodeSignature -FilePath 'cryptomator.msi' -ErrorAction Stop).SignerCertificate.Thumbprint
+
+ $DocPath = 'docs/security/verify-installers.md'
+ $Content = Get-Content -Path $DocPath -Raw
+
+ $CurrentThumbprintRegex = [regex] ([regex]::Escape($env:AUTOMATION_MARKER) + '`[A-F0-9]+`')
+ $UpdatedContent = $CurrentThumbprintRegex.Replace($Content, ($env:AUTOMATION_MARKER + '`' + $Thumbprint + '`'), 1)
+ if ($UpdatedContent -eq $Content) {
+ throw 'Failed to update the current Windows thumbprint in verify-installers.md.'
+ }
+ $Content = $UpdatedContent
+
+ $MarkedRow = (Get-Content -Path $DocPath | Where-Object { $_.TrimStart().StartsWith('|') -and $_.Contains($env:AUTOMATION_MARKER) } | Select-Object -First 1)
+ if ($null -eq $MarkedRow) {
+ throw 'Failed to find the marked Windows certificate table row in verify-installers.md.'
+ }
+
+ $PreviousRow = $MarkedRow.Substring(0, $MarkedRow.IndexOf($env:AUTOMATION_MARKER)).TrimEnd() + " |"
+ $NewRow = "| $env:DESKTOP_VERSION |" + '`' + $Thumbprint + '`' + "$env:AUTOMATION_MARKER |"
+ $Content = $Content.Replace($MarkedRow, $NewRow + "`r`n" + $PreviousRow)
+
+ Set-Content -Path $DocPath -Value $Content
+ env:
+ AUTOMATION_MARKER: ''
+ - name: Commit and push
+ id: commit-and-push
+ run: |
+ git config user.name "cryptobot"
+ git config user.email "cryptobot@users.noreply.github.com"
+ git config push.autoSetupRemote true
+ git stage docs/security/verify-installers.md
+ if git diff --cached --quiet; then
+ echo "No changes to commit"
+ echo "changed=false" >> "$GITHUB_OUTPUT"
+ exit 0
+ fi
+ git commit -m "Update Windows section for verifying installers for release ${DESKTOP_VERSION}"
+ git push
+ echo "changed=true" >> "$GITHUB_OUTPUT"
+ - name: Create pull request
+ id: create-pr
+ if: steps.commit-and-push.outputs.changed == 'true'
+ run: |
+ printf "Created by $GITHUB_SERVER_URL/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID" > pr_body.md
+ PR_URL=$(gh pr create --title "Desktop release ${DESKTOP_VERSION}" --body-file pr_body.md)
+ echo "url=$PR_URL" >> "$GITHUB_OUTPUT"
+ env:
+ GH_TOKEN: ${{ secrets.CRYPTOBOT_PR_TOKEN }}
+ - name: Slack Notification
+ if: steps.commit-and-push.outputs.changed == 'true'
+ uses: rtCamp/action-slack-notify@e31e87e03dd19038e411e38ae27cbad084a90661 # v2.3.3
+ env:
+ SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_CRYPTOMATOR_DESKTOP }}
+ SLACK_USERNAME: 'Cryptobot'
+ SLACK_ICON: false
+ SLACK_ICON_EMOJI: ':bot:'
+ SLACK_CHANNEL: 'cryptomator-desktop'
+ SLACK_TITLE: "Docs update PR created for release ${{ github.event.client_payload.version }} ."
+ SLACK_MESSAGE: "See <${{ steps.create-pr.outputs.url }}|PR> on how to proceed."
+ SLACK_FOOTER: false
+ MSG_MINIMAL: true
diff --git a/docs/security/verify-installers.md b/docs/security/verify-installers.md
index 608067c..9bd86d5 100644
--- a/docs/security/verify-installers.md
+++ b/docs/security/verify-installers.md
@@ -28,24 +28,53 @@ If shown, you can ignore the following warning:
## Windows (exe, msi) {#windows}
-Our Windows installers are signed using a code signing certificate. You can verify the signature in five simple steps:
+Our Windows installers are signed using a code signing certificate. You can verify the signature in three simple steps:
-
+1. Open Terminal or PowerShell (found in Windows Start menu).
+2. Run either of the following commands to check the signature of the corresponding file:
+ ```pwsh
+ Get-AuthenticodeSignature -FilePath "~\Downloads\Cryptomator-*.msi"
+ Get-AuthenticodeSignature -FilePath "~\Downloads\Cryptomator-*.exe"
+ ```
+3. Verify that the output includes:
+ - Column `SignerCertificate` with value `20F30D7C5B1AB3ACAFA4AB27874ACBC4B47B0697`(*)
+ - Column `Status` with value `Valid`
+ - no errors
+
+*for older releases, see [below](#windows-all-versions).
+
+If the installer is properly signed, you should see output similar to:
+```text
+SignerCertificate Status StatusMessage Path
+----------------- ------ ------------- ----
+BB0E... Valid Signature verified. Cryptomator-1.19.1-x64.msi
+```
-1. Right-click on the file and click on Properties.
+You can also inspect the certificate manually:
+1. Right-click on the cryptomator installer file and click on Properties.
2. Select the Digital Signatures tab: It should show one or more signatures by `Skymatic GmbH` under Embedded Signatures.
- For releases since 1.18.0, the `exe` release artifact will have two signatures, and the `msi` release artifact will have one signature.
3. Click on the first signature, and then click Details.
-4. Click on View Certificates.
-5. Click the Details tab. Different Cryptomator versions are signed with different certificates. The following list shows for each version the certificate serial number:
- - Version 1.19.2: `33000890b1b9dff7ee6e525b2d0000000890b1`
- - Version 1.19.1: `33000852bd6c3a151ff92180ee0000000852bd`
- - Version 1.19.0: `3300083c47651e1daeb99b00eb000000083c47`
- - Version 1.18.1: `330007d28ad57305892a81cac600000007d28a`
- - Version 1.18.0: `3300052c3561155e2baf361702000000052c35`
- - Versions 1.6.11 to 1.17.1: `00d77e4f8b938f56ae265cd08e9193490c`
- - Versions 1.4.12 to 1.6.10: `63c45bff1a148d60ed2994d3a2639034`
- - Versions up to 1.4.11: `1a360f3933964c71f14e8754d94615d4`
+4. Click on View Certificates and select the field `Thumbprint`.
+
+
+
+### Certificate thumbprints for all Cryptomator versions {#windows-all-versions}
+
+Every Cryptomator installer is signed with a certificate. A certificate is identified by its thumbprint. The signing certificate changed over time and the following table shows for each version the certificate thumbprint:
+
+| Version(s) | Certificate Thumbprint |
+|---------------------|--------------------------------------------|
+| 1.19.2 | `20F30D7C5B1AB3ACAFA4AB27874ACBC4B47B0697` |
+| 1.19.1 | `BB0EEBF8E92E4584DF4B6AE4F9577B60BEB5DF4C` |
+| 1.19.0 | `14524B1F8A3A1CA8B24B769C7C6DC92851120B22` |
+| 1.18.1 | `53FA929F6D50D5E2AE59A7C9A9750D373AFF7D40` |
+| 1.18.0 | `4DC9A70B94F731562A9C37B4391C4FD5BEC72C94` |
+| 1.6.11 to 1.17.1 | `5FC94CE149E5B511E621F53A060AC67CBD446B3A` |
+| 1.4.12 to 1.6.10 | `FF52240075AD7D14AF25629FDF69635357C7D14B` |
+| up to 1.4.11 | `6FDEC9DFCFE59E6BAEE64B7ED97F00E120E70D97` |
+
+
## macOS (app) {#macos}