GitHub ActionsでPrivate Submoduleをcheckoutできないときの権限確認

親repositoryとprivate submoduleの取得を分け、checkout入力、子URL、token対象、eventと固定commitを確認します。

AIものさし編集部

GitHub Actionsで親repositoryのcheckoutは成功するのにprivate submoduleだけ取得できない場合、子repositoryへの認証を別に確認します。親のGITHUB_TOKENへwriteを追加しても、別repositoryへのアクセス範囲が自動的に増えるわけではありません。失敗した子のURL、固定commit、実際の認証経路を特定します。

本稿はprivate Git submoduleの取得診断です。repositoryアクセス、token発行、secret登録、SSH接続、checkoutやworkflow実行は実施していません。認証情報を含まない架空の確認表を使い、取得成功を測定した記事としては扱いません。

親checkoutと子の取得を分ける

失敗stepと最初のerrorを確認します。親repositoryを取得できたことは、submoduleを取得したことではありません。checkout actionのsubmodules入力が未設定なのか、子を取得しに行って拒否されたのかを分けます。

表は横にスクロールできます

状況最初の確認まだ断定しないこと
子のdirectoryが空submodules入力と対象pathtoken失効
Repository not found子URLとアクセス主体repository削除
Permission denied (publickey)SSH URLとkeyの適用HTTPS token不足
nestedの子だけ失敗再帰設定と各子のアクセス親のcheckout障害
commitを取得できない親が固定した子SHAの存在権限だけが原因

.gitmodulesのpathとURL、親commitが記録する子のSHAを確認します。ローカルにある古いcheckoutや、手元のSSH agentで成功した結果を、runnerの認証条件と同一視しないようにします。ログを共有するときは、URLに埋め込まれた認証情報も除きます。

checkoutの入力とバージョンを確認する

actions/checkoutの公式README(新しいタブで開く)は、submodules入力の既定をfalse、再帰取得をrecursiveとして説明しています。子が必要なのに無効なら、その設定を確認します。nested submoduleがある場合は、最上位の一件が取れたことだけで終えません。

実際に固定しているactionのバージョンまたはSHAと、その版の入力・runner要件を照合します。最新版へ変えれば認証問題も直ると考えず、runtime条件、変更点、取得範囲を分けて判断します。公式READMEの現行版にはforkコードを高権限eventでcheckoutする場合の保護も案内されています。認証エラーを理由にその保護を無効化する手順にはしません。

tokenの対象repositoryを照合する

公式READMEは、github.tokenが現在のrepositoryにscopeされ、別のprivate repository取得には別の認証が必要になることを説明しています。子のrepositoryへ読取可能な、組織で許可された認証方式を確認します。

表は横にスクロールできます

認証方式確認する範囲避ける対応
GITHUB_TOKEN現在のrepository・job権限writeを付ければ別repoへ届くと仮定
GitHub App tokeninstallationと対象repository・権限親だけのinstallationで全子取得を期待
PATowner・対象repo・必要権限・有効状態全repositoryの広いtokenへ即置換
SSH key接続host・key・対象repoの許可host key検証を無効化

この表は認証方式の選択肢で、すべてを新規発行する指示ではありません。利用中の方式を一つ特定し、親と各子に必要な読取範囲だけを確認します。組織の承認やSSO等の条件がある場合は、管理者がそのtoken・identityの条件を確認します。secret値をechoして渡っているか試す方法は使いません。

HTTPSとSSH、nested先の違いを見る

子URLがHTTPSかSSHかを確認し、checkoutに渡したtokenまたはkeyが、その取得経路へ適用されるかを調べます。公式checkout資料には、ssh-keyがない場合のGitHub SSH URLからHTTPSへの変換条件もあります。自分の設定でどの経路になったかを確認し、URLの表記だけから利用keyを断定しません。

nested submoduleが別organizationや別hostなら、そのアクセス条件も別です。一つのSSH keyやtokenが、すべての階層へ使える前提にしないようにします。host keyの問題なら、信頼できる公式情報と組織手順に従って既知hostを設定し、StrictHostKeyCheckingを切って通す処置を避けます。

認証を通せても、親が指定した子commitが取得できなければ別問題です。子の履歴・参照状態とアクセス範囲を確認し、診断のために勝手に子の最新branchへ替えません。親が想定したバージョンと異なるコードを取れば、取得成功でも再現性が変わります。

eventによるsecret条件を確認する

通常のpushで成功しfork PRで失敗する場合は、同じ認証情報が提供される条件かを確認します。secretが渡らない経路へ、private submodule必須の処理を置いていないかを見ます。privileged eventへの切替で未信頼コードとsecretを同じjobへ集める対応にはしません。

secretが必要な信頼済み検証と、未信頼入力の検証をどう分けるかを、repositoryの運用担当と決めます。実行対象を制限する場合も、何を検証できなくなるかを明記します。取得をskipしたのに、必要な子コードまで検証済みと報告しないようにします。

取得結果を固定commitで確認する

変更前のaction設定、認証方式、対象repo、親・子SHAを残します。許可された検証では、各子が親の想定SHAで初期化され、必要なファイルがあり、nestedも含めた処理が進むことを確認します。認証成功のlogだけで、実際に必要なバージョンが揃ったと扱いません。

失敗したら、増やした入力や取得設定だけを戻せるようにします。検証用tokenを使った場合は、組織の期限・失効・secret管理手順へ戻します。完了記録には、失敗した階層、原因となったURL・認証・commit条件、変更した最小範囲、未検証のeventを残します。