🪟

[2025年版] Azure Trusted SigningでWindowsアプリにコード署名する

2025/02/24に公開

はじめに

Electronで作ったWindowsアプリを配布して実行できるようにしたい!
そんなときに避けて通れないのがコード署名(code signing)です。Windowsのコード署名なんて簡単だろうと勝手に思っていたのですが、地味に面倒で苦労したのでその手順を備忘として記載します。

基本的な流れは以下の記事の通りで、初心者に分かりづらかったポイントに絞って補足記載していきます。
https://learn.microsoft.com/ja-jp/azure/trusted-signing/quickstart?tabs=registerrp-portal%2Caccount-portal%2Corgvalidation%2Ccertificateprofile-portal%2Cdeleteresources-portal
https://qiita.com/yoshi-taka/items/487cb94f8f60d016eaa1
https://melatonin.dev/blog/code-signing-on-windows-with-azure-trusted-signing/
https://www.sciement.com/tech-blog/code-signing/code-signing/

また、こちらのスクラップも参考にさせていただきました。
https://zenn.dev/shinshin86/scraps/66530d26e3a64b

Azure Trusted Singingとは

まずAppleと違ってWindowsのコード署名はいくつかの方法があります。主流なのは証明書を購入するパターンですが、安くても3万円前後、諸々便利なEV署名だと5万以上はかかってきます。しかも、証明書の入手はスムーズに進んでも3日はかかるようです。さすがに厳しすぎる。

それを低コストで実現してくれるサービスがAzure Trusted Signingであり、最近(2024年)Microsoftから提供開始されました。ありがたや。ただ、まだあまり浸透していないのか、調べても情報はあまり多くない印象です。
https://forest.watch.impress.co.jp/docs/serial/yajiuma/1587364.html

Azureのセットアップ

大まかな流れは以下の通りです。

  1. Azureアカウントの作成
  2. Subscriptionを作成
  3. 署名リソースプロバイダーを登録
  4. Trusted Signing Accountの作成
  5. ID検証要求
  6. ID検証
  7. 証明書プロファイルの作成

冒頭の記事に沿って進めていきつつ、詰まったポイントを以下記載します。

step1については、アカウント作成時に"pay as you go"を選択することでSubscription作成も自動でやってくれました(こちらに記載の通り)。

step4については、リージョンにUS Westを選択したところエラーが出ました。2025年2月現在、US Westは使えないようです。

step5です。私は個人開発者として申請しました。個人開発者だとSignTool.exeでは署名できない説があるようですが、私はCIからコード署名できたので今のところは問題なさそうです(Windows端末持ってないので動作確認はできてません)。

で、このID検証のフォームはGメールを利用すると速攻弾かれるので、個人・法人関係なく、独自ドメインのメールアドレスを持っていることが必須条件のようです。独自ドメインのメールを安価に入手する方法は後述します。

独自ドメインのメールを使ったら数分で検証リンクが届き、そこから本人確認(step6)をします。セルフィーの撮影が謎に厳しく何度か失敗しましたが、検証自体は10分もかからずにサクッと終わりました。

独自ドメインのメールを入手する

一般的には独自ドメインのメールアドレスを作るにはレンタルサーバーとドメインを購入しなければいけないのですが、Cloudflare Email Routing(受信)とGmail(送信)を組み合わせることで、ドメインのみの費用で済ますことができました。

手順としてはこちらの記事が非常に分かりやすく、ドメインさえ決まってしまえば15分くらい設定できました。
https://qiita.com/rokuosan/items/e3415ea30ad5e48d3b0f
https://note.com/ogawa_analyze/n/n1c96bf19412e#d8976f17-3e38-41f8-bec8-db3dcd7d5575

GitHub ActionsでWindowsのコード署名を実行

Windowsアプリをビルドするには基本的にWindows端末が必要ですが、私はWindows端末を持っていないのでCIのWindows環境でビルドします。

動作環境

  • macOS Sonoma 14.3.1
  • electron@34.0.2
  • electron-builder@25.1.8

Azure側の設定

以下の記事を参考に、App Registrationを作成して"Trusted Signing Certificate Profile Signer"ロールを付与しました。
https://melatonin.dev/blog/code-signing-on-windows-with-azure-trusted-signing/#step-4-create-app-registration-user-credentials
https://qiita.com/yoshi-taka/items/cb5628cd980d39bd29e1

私はいったんOIDCのセットアップはせずに、英語の記事の方法(シークレットを作る)で行いました。

GitHub Actions

build-windows.yml
name: Build Windows App

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:

permissions:
  contents: write

jobs:
  build-windows:
    runs-on: windows-latest
    name: Build and Sign Windows App
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"
          cache: "npm"

      - name: Install dependencies
        run: npm ci

      - name: Build Windows app
        run: |
          npm run build:electron && npm run build
          npx electron-builder --win --x64 -p never

      - name: Codesign with Azure Trusted Signing
        uses: azure/trusted-signing-action@v0
        with:
          azure-tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          azure-client-id: ${{ secrets.AZURE_CLIENT_ID }}
          azure-client-secret: ${{ secrets.AZURE_CLIENT_SECRET }}
          endpoint: <signing endpoint>
          trusted-signing-account-name: <signing account name>
          certificate-profile-name: ${{ secrets.AZURE_CERT_PROFILE_NAME }}
          files-folder: ${{ github.workspace }}\dist
          files-folder-filter: exe,dll
          file-digest: SHA256
          timestamp-rfc3161: http://timestamp.acs.microsoft.com
          timestamp-digest: SHA256
          exclude-environment-credential: false
          exclude-workload-identity-credential: true
          exclude-managed-identity-credential: true
          exclude-shared-token-cache-credential: true
          exclude-visual-studio-credential: true
          exclude-visual-studio-code-credential: true
          exclude-azure-cli-credential: true
          exclude-azure-powershell-credential: true
          exclude-azure-developer-cli-credential: true
          exclude-interactive-browser-credential: true

      - name: Create Release
        if: startsWith(github.ref, 'refs/tags/')
        uses: softprops/action-gh-release@v2
        with:
          files: |
            dist/*.exe
            dist/*.blockmap
            dist/latest.yml
          draft: false
          prerelease: false
          generate_release_notes: true

私はelectron-builderを使っていて、これはビルド時に署名やリリースの公開(Publish)も一緒にしてくれるのですが、今回の方法ではビルドした後にAzure Trusted Signingでコード署名をしているので、ビルド時にはPublishされないように -p never をつけて、最後にGitHub Releasesにアップロードするステップを入れています。

Discussion