GitHub の Immutable releases でリリースを変更不可にする

| 4 min read
Author: masahiro-kondo masahiro-kondoの画像

はじめに

#

先月 Immutable releases が GA になりました。

これによりリリースが公開後に変更されていないことを確認でき、改ざんや偶発的な変更を回避できるようになります。

変更不可リリースの特徴

#

ドキュメントは以下で参照できます。

変更不可リリースは以下のような特徴があります。

  • Git タグは移動または削除できない:リリースに関連付けられている Git タグは特定のコミットにロックされ、変更または削除することはできなくなります。
  • リリースアセットを変更または削除することはできない:リリースにアタッチされているすべてのファイルは、変更または削除から保護されます。

リリース構成証明が自動的に生成され、リリース タグ、コミット SHA、アセットなどの検証が可能になります。

変更不可リリースが有効な場合、そのリポジトリを削除し、同じ名前の新しいリポジトリを作成した場合でも、元のリポジトリの変更不可リリースに関連付けられたタグを再利用することはできなくなります。これは強力な保護機能ですね。

使ってみる

#

筆者がメンテナンスしている野良 Cosense アプリ sbe のリポジトリで設定してみました。

Enable release immiutability

Information

Immutable releases は、リポジトリ単位、オーガニゼーション単位で設定可能です。

一度リリースしてしまうとリポジトリのコミッタでも変更はできないため、以下のようにドラフトリリースで作業する手順が推奨されています。

  • ドラフトリリースを作成
  • 全てのアセットをドラフトリリースにアタッチ
  • ドラフトリリースを正式リリースにする

ちょうど sbe の変更が溜まっていたので、ベストプラクティスに従ってリリースドラフトを作成します。

Create draft release

保存されたドラフトリリースはまだ非公開で変更可能です。

Draft release

Information

このアプリのリリース用ワークフローではタグ作成を契機にリリースを作るようにしています。
softprops/action-gh-release という Action を使っています。リリース成果物のアタッチもやってくれます。prereleasetrue にすることで、ドラフトリリースを作成してくれます。

    - name: Publish
      uses: softprops/action-gh-release@v2
      with:
        files: |
          dist/**/*.exe
          dist/**/*.deb
          dist/**/*.AppImage
          dist/**/*.dmg
        prerelease: true

添付ファイルや差分を指差し確認してリリースを発行します。

Publish release

Immutable release を有効にしていると確認のダイアログが出ます。

Confirm to publish

発行されたリリースには Immutable マークが付きました。

Immutable mark

アセットには、リリースの attestation (証明) の JSON ファイルも追加されています。

Release attestation

編集画面では、リリースの説明などは編集可能ですが、タグやアセットは編集できない旨のメッセージが表示されます。

Cannot Edit tag or asset

リリースを検証する

#

利用者は Immutable release で作成された変更不可リリースを GitHub CLI で検証できます。

リリースが存在し、かつ不変であることを検証するには、クローンしたリポジトリのディレクトリ内で release verify コマンドを実行します。

gh release verify RELEASE-TAG

sbe の v3.8.0 リリースを検証すると GitHub API を使って証明を読み取り表示してくれます。

$ gh release verify v3.8.0

Resolved tag v3.8.0 to sha1:1f3f380d33f022230046a3200a67950ea027c8a1
Loaded attestation from GitHub API
✓ Release v3.8.0 verified!

Assets
NAME                     DIGEST                                                                 
sbe-3.8.0-universal.dmg  sha256:ab1c2595601136bf82aa7594d48bc764fe6f226ed1071c52441eb531f34e0252
sbe-3.8.0.AppImage       sha256:de1797b12152531df71e78519d660e32e1a79dca203bc3201d85b2facfe4b5a9
sbe-Setup-3.8.0.exe      sha256:a4a8d6fe8ddde6e1a2005a29d7e2759511cb537427e4a0ff03440c5e9f48fb94

ローカルにある成果物がリリース成果物と完全に一致していることを検証するには release verify-asset コマンドを使用します。

gh release verify-asset RELEASE-TAG ARTIFACT-PATH

リリースのアセットから macOS 用ユニバーサルインストーラのバイナリをダウンロードして検証してみました。

$ gh release verify-asset v3.8.0 ~/Downloads/sbe-3.8.0-universal.dmg 
Calculated digest for sbe-3.8.0-universal.dmg: sha256:ab1c2595601136bf82aa7594d48bc764fe6f226ed1071c52441eb531f34e0252
Resolved tag v3.8.0 to sha1:1f3f380d33f022230046a3200a67950ea027c8a1
Loaded attestation from GitHub API

✓ Verification succeeded! sbe-3.8.0-universal.dmg is present in release v3.8.0
Information

アセットの証明には Sigstore の署名技術が利用されています。ソフトウェアの出所情報を検証可能し、ソフトウェアサプライチェーンの安全性を高めるための技術です。かなり前の記事ですが以下で紹介しています。

さいごに

#

以上、Immutable releases の紹介でした。一定数ユーザーがいる OSS では変更不可リリースを採用する方がいいでしょう。

GitHub Actions でもサードパーティの Action を利用する際は、不意な変更の影響を受けないためにバージョンだけでなくコミットハッシュまで指定して固定することもあります。変更不可リリースを採用してくれる Action が増えれば使う側も安心ですね。

豆蔵では共に高め合う仲間を募集しています!

recruit

具体的な採用情報はこちらからご覧いただけます。