Go modules の修正 PR の開発
- 状態: 実装済み(検証用のリポジトリで PR の作成、検証用のホストの Kubernetes で作業用 Pod の動作を確認)
- 開始日: 2026年10月29日
- 最終更新: 2026年10月30日
目的
npm・pnpm・pip・uv を対象にしていた言語パッケージの修正 PR を、Go modules に広げる。
稼働イメージの Go のバイナリを Trivy が gobinary として検出した所見から、対応付けたディレクトリの go.mod・go.sum を更新する PR を作る。
方針
- 既存の言語パッケージと同じく、作業用コンテナで公式ツールの
goコマンドを動かす - 作業用コンテナの結果は未信頼として扱い、KestreLynx で検査する
決定事項
バイナリとの対応
- メインモジュールのパスが、対応付けた
go.modのmoduleと一致するバイナリの所見だけを扱う - ベースイメージに含まれる別の Go のツールの所見は、修正計画に出さない
- バイナリに組み込まれた依存の版が
requireと一致しない場合は、手動対応にする
Go 自体の所見
- 標準ライブラリの
stdlibの所見は、PR にしない go.modの更新では直らない- 修正計画の別の項目で「この版以上の Go でビルドし直すと直る」と案内する
更新と go の行
- すべての対象を1回の
go getで更新し、go mod tidyは実行しない goの行は、更新後のモジュールのgo.modが宣言する版まで上がることがある- 更新後の
goの行が、稼働バイナリをビルドした Go の版を超える場合は手動対応にする - ビルドに必要な Go の版を、利用者が使っている版より上げる判断は任せる
別の対象が高い版を要求する場合
- 別の対象からより高い版を要求される対象は
go getの指定から外し、依存の要求によって版を上げる - 対象それぞれの修正版を
go getに正確に指定すると、ある対象の新しい版が別の対象をより高い版で要求する場合に失敗する- 例えば、
golang.org/x/net v0.60.0はgolang.org/x/text v0.42.0を要求するため、x/textの修正版であるv0.41.0を同時に指定できない
- 例えば、
- 上がった版は、ほかの付随する更新と同じ検査で確かめる
検査で確かめる版
- 更新の前後で脆弱性を比べるのは、
go.modのrequireに書かれている版 - 例えば今回の検証の PR では、更新前の
golang.org/x/net v0.20.0・golang.org/x/text v0.14.0と、更新後のx/net v0.60.0・x/text v0.42.0を比べる - 比べ方は npm・uv と同じく、モジュールと脆弱性の組
go.modに書かれている版だけを見れば足りるgo buildは既定の-mod=readonlyで、go.modに書かれている版のモジュールだけを使う- 必要なモジュールが
go.modにない場合や、書かれている版が必要な版より低い場合は、goコマンドが別の版を選ばず、updates to go.mod neededでビルドが止まることをgo1.26.0で確認 - そのため、作業用コンテナが不完全な
go.modを返しても、確かめていない版がビルドに入ることはなく、ビルドが失敗するだけになる - 依存先の
go.modをたどって見つかる版までは調べない - 各モジュールの
go.modは古い版の依存も要求しているため、たどるとビルドで使われない古い版が大量に集まる - 例えば
x/netをv0.20.0からv0.23.0に上げるだけでも37版が集まり、2019年のgolang.org/x/cryptoやx/text v0.3.0など、使われない版の既知の脆弱性88件で必ず手動対応になった - この確認は、利用者が
go buildを既定のまま実行することを前提にする - ビルドの前に
go get・go mod tidy・-mod=modのビルドを実行すると、goコマンドが別の版を選ぶため、確認の範囲から外れる - PR 本文に、この前提と CI で実行する
go build -mod=readonly ./... && go test -mod=readonly ./...を書く
付随する更新と go.sum
- 付随する更新は、対象の修正版の
go.modの要求からたどれるものだけを認める go.sumはsum.golang.orgの記録と照合する- 足りない行は KestreLynx が補って PR 本文に書く
検証方法
単体テスト
go.modの解析とバイナリとの対応を確認goの行の変更とgo.sumの照合を確認- 付随する更新の説明と PR 本文を確認
結合テスト
手元の Docker で、公式 golang イメージの Go 1.26・1.27、proxy.golang.org・sum.golang.org・Trivy を使った。
golang.org/x/net v0.20.0 を使うモジュールの更新を、次の観点を含む5通りで確認した。
- 直接依存だけの更新
golang.org/x/textも上がる更新goの行が1.22から1.25.0に上がる更新- Go 1.26 と Go 1.27 の作業用イメージでの更新
5通りすべてが PR の候補になった。
実環境
手元の Docker で KestreLynx を動かし、検証用のリポジトリに置いた Go のアプリケーションを対象にした。 修正計画から GitHub の PR の作成までを確認した。
| 項目 | 構成 |
|---|---|
| ビルドに使った Go | Go 1.26.10 |
| 使用するモジュール | golang.org/x/net v0.20.0・golang.org/x/text v0.14.0 |
検証結果
2026年10月30日の実環境での検証結果を示す。
修正計画と作業用イメージ
| 確認項目 | 結果 |
|---|---|
| 検出した所見 | golang.org/x/net に HIGH の所見8件(修正版は 0.23.0〜0.60.0)、golang.org/x/text に2件(修正版は 0.39.0・0.41.0) |
| 目標版 | x/net v0.60.0・x/text v0.41.0 |
| 作業用イメージ | 入力の go の行と x/net v0.60.0 の go.mod の go 1.26.0 から、golang1.26(1.26.10)を選択 |
PR の変更と更新後の確認
| 確認項目 | 結果 |
|---|---|
| PR の作成 | 修正計画から検証用のリポジトリに GitHub の PR を作成 |
go.mod の go の行 |
1.22 → 1.26.0 |
golang.org/x/net |
v0.20.0 → v0.60.0 |
golang.org/x/text |
v0.14.0 → v0.42.0(// indirect) |
x/text の更新理由 |
go get の指定から外れ、x/net v0.60.0 の要求で v0.42.0 になった理由を PR 本文の実行時のメモに表示 |
go.sum |
4行追加 |
| 更新前後のスキャン | 解消10件、残存0件、新規0件 |
| PR のブランチでの確認 | go build -mod=readonly ./... と go vet -mod=readonly ./... が通過し、ビルドで使われる版は x/net v0.60.0・x/text v0.42.0 だけ |
Kubernetes の作業用 Pod
| 確認項目 | 結果 |
|---|---|
| 作業用 Pod の作成 | 検証用のホストの K3s(v1.36.5)で、Pod Security の restricted と作業用 Pod の形を制限する admission policy を適用した作業用 Pod の名前空間に、言語パッケージの更新の作業用 Pod を作成 |
| Go の結合テスト | 直接依存だけの更新、golang.org/x/text も上がる更新、go の行が 1.22 から 1.25.0 に上がる更新、Go 1.26 と Go 1.27 の作業用イメージでの更新の5通りを作業用 Pod で実行し、すべて PR の候補になった |
| 作業用イメージの動作 | digest で固定した公式 golang イメージ(Go 1.26.10・1.27.3)が、ルートファイルシステムが読み取り専用の Pod で動き、go get と結果の受け取りまで完了 |
| 終了後の作業用 Pod | 終わった作業用 Pod は残らなかった |
| Go に対応した版の反映 | 本番運用環境と検証用のホストに反映済みで、どちらも Go のアプリケーションは動いていないため、実際の Go の更新はまだない |
未検証・次の作業
- arm64 での動作確認
- 本番運用環境での Go のアプリケーションの更新の確認
更新履歴
2026年10月29日
- 計画・更新・PR の実装と結合テスト
2026年10月30日
- 実環境での PR の作成確認
- 別の対象が高い版を要求する場合の扱いの記録
- Kubernetes の作業用 Pod の動作確認
この記事は、KestreLynxの開発記録です。KestreLynxについて