先日、JetBrains IDE向けの railroads プラグインの 0.5.1 をリリースしました。ありがたいことに、多くの方々に使っていただけているようです。
https://plugins.jetbrains.com/plugin/24076-railroads/
一方で、 railroads プラグインのリポジトリのセキュリティ設定がおろそかになっていたことから、設定を見直すことにしました。
どのような設定にするのが良いか調べてみたところ、次のページが参考になりました。ありがとうございました。
- リポジトリを保護するためのクイック スタート - GitHub ドキュメント
- 自分のOSSリポジトリにGitHubのセキュリティ設定を入れ、自分用の手順書を作った - $shibayu36->blog;
- GitHubでサプライチェーン攻撃を防ぐ設定 - Plan 9とGo言語のブログ
そこで、今回どんな設定を行ったかをメモとして残します。
目次
- 環境
- GitのメールアドレスをGitHubが提供しているnoreplyにする
- SSH鍵でコミットに署名する
- GitHubのドキュメントに従った設定見直し
- shibayu36さんのチェックリストに従った設定
- lufiabbさんの記事に従った設定
- Immutable release実現のため、GitHub Actionsを見直し
- Approval for running fork pull request workflows from contributors の設定変更 (2026/5/17 追記)
- おわりに
環境
- mac
GitのメールアドレスをGitHubが提供しているnoreplyにする
GitHubの公式ドキュメントに従い設定します。
コミットメールアドレスを設定する - GitHub ドキュメント
% git config --global user.email "1299734+thinkAmi@users.noreply.github.com"
SSH鍵でコミットに署名する
Gitでは、いくつかの方法でコミットへ署名できます。
今回はGitHubでも対応しているSSH鍵をコミット署名に使います。また、既存のSSH鍵を流用せず、新しくSSH鍵を作成し、署名専用として使うことにします。
SSH コミット署名の検証 | コミット署名の検証について - GitHub ドキュメント
なお、Gitの初期設定はこんな感じだとします。
% git config --list credential.helper=osxkeychain user.name=thinkAmi user.email=1299734+thinkAmi@users.noreply.github.com
署名で使うSSH鍵を生成し、ssh-add --apple-load-keychain できるようにする
ドキュメントに従って生成します。今回はパスフレーズ付きで生成します。
新しい SSH キーを生成して ssh-agent に追加する - GitHub ドキュメント
% ssh-keygen -t ed25519 -C "1299734+thinkAmi@users.noreply.github.com" Generating public/private ed25519 key pair. Enter file in which to save the key (/Users/thinkami/.ssh/id_ed25519): /Users/thinkami/.ssh/id_github_thinkami Enter passphrase for "/Users/thinkami/.ssh/id_github_thinkami" (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /Users/thinkami/.ssh/id_github_thinkami Your public key has been saved in /Users/thinkami/.ssh/id_github_thinkami.pub The key fingerprint is: SHA256:ClXy4N6R80jCjpLcQgEyX25K6xtnCMnEokC8V8o353Q 1299734+thinkAmi@users.noreply.github.com The key's randomart image is:
次に、作成したパスフレーズ付きでSSH鍵を ssh-agent へ追加します。
Adding your SSH key to the ssh-agent | 新しい SSH キーを生成して ssh-agent に追加する - GitHub ドキュメント
% ssh-add --apple-use-keychain ~/.ssh/id_github_thinkami Enter passphrase for /Users/thinkami/.ssh/id_github_thinkami: Identity added: /Users/thinkami/.ssh/id_github_thinkami
署名の都度パスフレーズを入力するのは手間なこと、OSを起動するたびに ssh-add --apple-use-keychain するのは手間なので、設定を行います。
接続用のSSH鍵と共用する場合は .ssh/config へエントリを追加すれば良さそうですが、今回はGitのコミット署名用のSSH鍵なので、その方法が使えません。
man ssh-add すると
--apple-load-keychain
Add identities to the agent using any passphrase stored in the user's keychain.
との記載がありました。また、以下のブログでも --apple-load-keychain が使えそうな記載があります。
Macのssh-agent | 2022年4月 – Mad Overload
そこで、 .zprofile へ --apple-load-keychain を使ってキーチェーンからロードするよう記載します。
なお、ssh agentを使える環境で実行したい、かつ、追加が失敗してもスルーしたいことから、if を入れたり /dev/null へ捨てたりしています。
if [[ -n "$SSH_AUTH_SOCK" ]]; then /usr/bin/ssh-add --apple-load-keychain ~/.ssh/id_github_thinkami >/dev/null 2>&1 || true fi
SSH鍵を署名だけで使うようGitHubへ設定する
続いて、SSH鍵をGitHubへと設定します。
GitHub アカウントへの新しい SSH キーの追加 - GitHub ドキュメント
SSH鍵の公開鍵をクリップボードへコピーします。
% pbcopy < ~/.ssh/id_github_thinkami.pub
GitHubのSSH Keysに Signing keys として保存します。
Gitの署名でSSH鍵を使う設定にする
こちらもGitHubの公式ドキュメントに従って設定します。
Git に SSH キーについて知らせる | Git へ署名キーを伝える - GitHub ドキュメント
% git config --global gpg.format ssh % git config --global user.signingkey ~/.ssh/id_github_thinkami.pub
設定できているか確認します。
% git config --list # ... user.signingkey=/Users/thinkami/.ssh/id_github_thinkami.pub # ... gpg.format=ssh
設定できたので、実際に試してみます。
コミットに署名する - GitHub ドキュメント
# 署名なし % git commit --allow-empty -m "test" [tmp/signing a1d6a91] test # 署名あり % git commit --allow-empty -S -m "test sign" [tmp/signing 6acd216] test sign
コミットをpushし、GitHubのコミット履歴を見ると、署名の有無で表示が異なっています。
ここで、ローカルでコミット時の署名を --show-signature を使って確認すると、エラーが出ていました。
% git log -2 --show-signature error: gpg.ssh.allowedSignersFile needs to be configured and exist for ssh signature verification commit 6acd2161feb4894ec546b6ac8862d8907f71820d (HEAD -> tmp/signing, origin/tmp/signing) No signature
そこで、ローカルの検証用に allowedSignersFile を設定します。
gpg.ssh.allowedSignersFile | Git - git-config Documentation
allowed_signers ファイルの置き場所はどこでも良さそうなので、GitLabやBitbucketのドキュメントにならい、 .ssh ディレクトリの中に置きます。
最初はファイルが存在しないため、新規作成しつつ、エントリを追加します。
% echo "1299734+thinkAmi@users.noreply.github.com $(cat ~/.ssh/id_github_thinkami.pub)" > ~/.ssh/allowed_signers
続いて、Gitへ設定します。
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
再度確認すると、署名がある方のみ Good が出ていました。
% git log -2 --show-signature --oneline 6acd216 (HEAD -> tmp/signing, origin/tmp/signing) Good "git" signature for *** with ED25519 key SHA256:*** test sign a1d6a91 test
良さそうなので、常に署名するよう、Gitで設定します。
git config --global commit.gpgsign true
動作確認します。良さそうです。
% git log -3 --show-signature --oneline 19a74d2 (HEAD -> tmp/signing) Good "git" signature for *** without S option 6acd216 (origin/tmp/signing) Good "git" signature for *** test sign a1d6a91 test
GitHubのドキュメントに従った設定見直し
GitHubのクイックスタートページと照らし合わせながら設定を見直します。
リポジトリを保護するためのクイック スタート - GitHub ドキュメント
リポジトリへのアクセスの管理
元々publicなリポジトリなので、見直すことはありませんでした。
依存関係グラフの管理
有効化してあったため、そのままにしました。
Dependabot alertsの管理
Dependabotは有効化してあったので、そのままにしました。
依存関係レビューの管理
ドキュメントに従って設定項目を探しましたが、それらしい設定が見当たらなかったので、特に対応しませんでした。
Dependabot security updatesの管理
有効化しました。
また、Dependabotが作る脆弱性のプルリクはある程度まとまっていたほうが良さそうと感じたことから、 Grouped security updates も有効化しました。
Dependabot version updatesの管理
最新のものを適用すると変更が大きいことから、今回は見送りました。
Code Security の構成
CodeQL analysis を有効化し、 Default を設定しました。
Secret Protectionの構成
有効化しました。
また、 Push protection も有効化しました。
shibayu36さんのチェックリストに従った設定
shibayu36さんが公開されているGitHub OSSセキュリティ最低限セットに従い、次のことを追加で行いました。
自分のOSSリポジトリにGitHubのセキュリティ設定を入れ、自分用の手順書を作った - $shibayu36->blog;
- Private vulnerability reporting / Security Advisories を有効化
- rulesets への追加
mainブランチを保護- 元々
mainブランチは保護していた mainブランチとバージョンタグを使ってプラグイン公開できるようなGitHub Actionsを設定しているため、より強固な設定を追加- 内容はshibayu36さん同様
- 元々
- バージョンtagの保護
mainブランチの保護と同様
なお、 SECURITY.md はいったん保留にしました。
lufiabbさんの記事に従った設定
- dependabotにcooldownを設定
- 追加した
- ただし、GitHub ActionsはcooldownのSemVer (例:
1.2.3) をサポートしていないので注意- Configuration of cooldown | Dependabot オプション リファレンス - GitHub ドキュメント
- サポートしていない状態だとエラーが出たので、次のプルリクのように修正した
なお、「Actionsのバージョンをハッシュで強制する」については、railroadsプラグインリポジトリの元となるテンプレート JetBrains/intellij-platform-plugin-template が対応していなかったため、現時点では見送りました。
Immutable release実現のため、GitHub Actionsを見直し
railroadsはGitHubのRelease機能を使ってJetBrainsマーケットプレイスへプラグインを公開しています。
もし、Immutable Releaseにすれば、リポジトリのReleaseにあるプラグインとマーケットプレイスへ公開したプラグインは同一になり、変更することもできません。
そのため、Immutable Releaseにしたいのですが、JetBrainsのプラグインテンプレートにあるGitHub Actionsが v2.4.0 の時点では、「プラグインを公開後に、GitHubのReleaseのアセットを gh release upload で更新する」という作りになっています。
https://github.com/JetBrains/intellij-platform-plugin-template/blob/2.4.0/.github/workflows/release.yml
これより、取れる方法としては次の2つでした。
- JetBrainsのプラグインテンプレートとの互換性を重視し、Immutable Releaseは諦める
- JetBrainsのプラグインテンプレートとの互換性は諦め、Immutable Releaseを導入する
JetBrainsのプラグインテンプレートへの追随を容易にするのを優先することを考えましたが、
- 今のご時世的に、Immutable Releaseのほうが良さそう
- AIもいるし、プラグインテンプレートへの追随はなんとかなりそう
となり、互換性は諦めて Immutable Releaseを導入することにしました。
Immutable releaseを導入するための設計
lufiabbさんの記事では「Immutable Releasesでアセットを追加する」に導入方法が記載されています。
Immutable Releasesでアセットを追加する | GitHubでサプライチェーン攻撃を防ぐ設定 - Plan 9とGo言語のブログ
railroadsのGitHub Actionsでは次の作りとなっていました。
build.ymlの最後で Draft releaseを作るrelease.ymlのプラグインを公開した後に、Releaseの成果物を入れ替える
そこで、次の流れにしようと考えました。
build.ymlbuildステップで、ビルドした成果物をアップロードするreleaseDraftステップで、ビルドした成果物を添付してDraftリリースを作る
release.yml- Releaseの成果物を入れ替えるステップ自体を削除する
GITHUB_TOKENによるgh pr createではCodeQLが動作しないので検討
これで良さそうとプルリクを眺めたところ、 release.yml の最後で作成する CHANGELOG.md を更新するプルリクエストに問題が出ました。
そのプルリクは gh pr create で作っているのですが、CodeQLが動作しませんでした。これにより、「 CodeQL analysis を有効」による「CodeQLによるチェックがパスすること」というプルリクのマージ可能条件が満たせず、マージできなくなっていました。
調べたところ、GitHubの仕様でした。
GITHUB_TOKEN を使ってプルリクを作る場合、GitHub Actionsによる操作は別のGitHub Actionsを実行できなくなっていることから、 CodeQLの pull_request トリガーが起動しなかったようです。
gh pr create don't trigger pullrequest: actions · cli/cli · Discussion #6575
ここで、そもそも CHANGELOG.md を更新するプルリクは不要かもしれないのではと考えました。
しかし、プラグインテンプレートでは「 CHANGELOG.md の内容を元に、JetBrains MarketplaceのWhat’s New へ表示される」という挙動を想定した作りとなっています。
この作りを変えるのはちょっと手間そうに感じたため、やはり CHANGELOG.md を更新するプルリク作成は残しておくことにしました。
さらに、次の記事にあるように GITHUB_TOKEN を使うのではなく、GitHub App Tokenを使ってプルリクを作ることを考えました。
GitHub Actions上でPRを作る時はsecrets.GITHUB_TOKENは使わない方がよさそう - くりにっき
しかし、「 CHANGELOG.md を更新する」は、プラグインの新しいバージョンをリリースする時くらいしか発生しません。
今のところrailroadsプラグインの機能充実は考えておらず、今後もAIエージェントの発展を考えると(残念ながら)機能充実は求められなさそうな気がします。
このような状況では、GitHub App Tokenという管理する秘匿情報を増やしてまで、運用を楽にする必要がなさそうでした。
そこで、「プラグインを公開したときに作られる CHANGELOG.md を更新するプルリクは、手動で空行などを加えてコミットすることで、CodeQLを実行させる」という運用でカバーすることにしました。
Draftリリースの作成・削除を調整
現在のワークフローでは gradle.properties にある pluginVersion に従って、Draftリリースのタグとバージョンを作成します。
しかし、次のような挙動が発生し得るのが気になりました。
- 最新バージョンが
0.5.1の時、 0.5.2 → 0.6.0 → 0.5.3 とプラグインの未公開バージョンを重ねた時、Draftリリースが残り続ける - 既存タグの削除、古いActionsの再実行、実行中に
mainブランチが進んだときなどに、タグ先のコミットとDraftに添付した成果物の内容がズレる
今まではプラグインのテンプレートに準じた動きとしていましたが、今回テンプレートとの互換性を諦めることから、このあたりにも手を入れることにしました。
そこで、次の対応を含めることにしました。
- Draftリリースを作る際、次を行う
- 既存のDraftリリースはすべて削除する
- 複数のバージョンのプラグインを同時にリリースする運用がないため
- 次の状況の場合、Draftリリースを作るのを止める
- JetBrainsマーケットプレイスへ公開済のバージョンでDraftリリースしようとした場合
- Draftリリースに添付する成果物について、タグに紐づくSHAと異なっていた場合
- 既存のDraftリリースはすべて削除する
この結果、 build.yml で使っているシェルがやや複雑になってしまいましたが、やむを得ないものとしました。
また、何をしたかったのかを忘れないよう docs/release-process.md へ内容を残しました。
ここまでの作業を行った結果、Immutable Releaseができるようになったと考えられたため、 Enable release immutability へチェックを入れました。
Approval for running fork pull request workflows from contributors の設定変更 (2026/5/17 追記)
サプライチェーン攻撃が流行し、GitHub Actionsのワークフローが悪用されることも目にしています。
このリポジトリでは基本的に自分しか機能追加を予定していないことから、 Approval for running fork pull request workflows from contributors の設定を変更することにしました。
変更先は Require approval for all external contributors とし、承認があるまではCIが走らないようにしています。
おわりに
以上が今回見直して対応した内容です。
今後も何かあれば適宜修正していこうと思います。
