セルフホストRunner · ワークロードIdentity · TTLと監査 · 判断行列
プラットフォームとモバイルの責任者が複数リージョンにまたがるリモートMac群でCIを回すとき、失敗の主因はコンパイラ速度ではなく、長寿命PAT、デプロイ用秘密鍵、横断コピースクリプトが各Runnerに常駐し、退職や端末再配布のたびに影響範囲が雪だるま式に広がることです。本稿は秘密リスクを三つの型に分類し、OIDCワークロードIdentityとPATとデプロイ鍵を粒度と失効と観測性で対比し、信頼ポリシーからRunner上の長寿命秘密ゼロへ至る六手順Runbook、TTLと最低限の監査フィールド、ホスティング形態×コンプライアンス×外向きレジストリの判断行列を示します。共有ビルドプール、観測可能タスクチェーン、成果物とキャッシュ局所性へ相互リンクし、Identity境界とバイト経路を同じ設計図に載せます。
ジャンプホスト、コード署名Identity、ウォームキャッシュが揃っていても、米国東部のディスクイメージに残った三年前のPAT、シンガポールノードへ複製されたkubeconfig、ステージングと本番で共有された秘密鍵がインシデントの起点になることがあります。根本原因は人の資格情報モデルが残り、パイプラインと環境に閉じた機械セッションへ移行できていない点です。このギャップはべき等性キーや共有プールのミューテックスと強く結びつき、構造化されたクレームが無いと「誰がログインしたか」しか追えず「どのビルドがどのAudienceを消費したか」が説明できません。ここでは事前フライトとして五つの税目に整理し、OIDCとPATの比較表に進む前にチーム合意を取ります。
運用現場では「とりあえず動く」設定が優先され、Runnerラベルとシークレット棚卸しの優先度が逆転しがちです。メッシュではリージョン数がそのまま複製回数になるため、暗号化ディスクや権限600だけでは読み手を絞れません。バックアップ、フォレンジック、サポート端末の読み取り経路まで含めて脅威モデルを更新し、SSHとVNCの前提で対話的更新と無人更新の要件差を先に固定すると、短命トークンの更新周期設計がブレません。
長寿命ディスク税:組織PATやkubeconfigをイメージ層、plist、ドットファイルへ焼き込むと、任意シェルが広い鍵束を引きずります。権限ビットだけではバックアップ経由の読み取りを止められません。
横断複製税:三リージョンへ同一秘密をrsyncすると、クローン逸脱のたびに暴露面が線形に増えます。成果物同期計画と混ざると、どの経路から漏れたかの切り分けが曖昧になります。
ローテーション遅延税:スプレッドシート管理はリリース列車と衝突すると更新が先送りされ、誰も触れないゾンビ資格情報が残り続けます。
環境混線税:本線ゲートと外部コントリビューションを同一Runnerが担うと複数トークンが同居し、弱いジョブ隔離のままステージAudienceが本番公開ステップへ流れ込みます。
観測盲目税:ビルドログにtoken_issuer、subject、ttl_remaining_secが無いと、事後にどの信頼連鎖がセッションを発行したかを証明できません。
この五項目をチェックリスト化してからOIDC導入の工数見積りを出すと、「とりあえずOIDC」では埋まらない観測穴が見えます。特にメッシュではリージョンごとのSTSとバケット整合が後から効いてくるため、次章の対照表をアーキテクチャノートに貼り、レビューで必ず差分比較できる状態にしてください。
万能解は存在せず、組織規模、監査粒度、外向きレジストリ方針に合わせて選びます。OIDCはリポジトリと環境へセッションを束ねるため多地域メッシュに適合しやすく、PATは導入は速いが監査に弱く、デプロイ鍵は狭い署名フローでは必要でも細粒度失効に向きません。信頼ポリシーへリージョン親和を書かないと、米国東Audienceをシンガポールが誤消費した瞬間にタイムゾーン当てずっぽうの調査が始まります。表は意思決定の共通言語として残し、四半期ごとにフィールド名の差異だけGitHub ActionsとGitLabで更新してください。
実務では「まずPATで通す」方が稟議は通りやすい一方、後追いでOIDCへ寄せるほどRunner再登録とワークフロー改修が重なります。早期に共有ビルドプールのRunnerグループとAudienceの対応表を一枚にまとめ、環境ごとに色分けした方が、運用引き継ぎで迷子になりません。
| 次元 | OIDCワークロードIdentity | 長寿命PAT | デプロイ秘密鍵 |
|---|---|---|---|
| 粒度 | リポジトリ、環境、ブランチ主体に任意クレームを追加可能 | しばしば組織またはユーザー横断、分割するとトークン数が膨張 | スロット当たり一鍵対が基本で証明書を増やさない限り粗い |
| 失効速度 | 信頼ポリシー無効化やTTL短縮で全体に効く | 管理画面操作とクライアントキャッシュ次第で遅延しがち | CRLやフィンガプリント拒否とクライアント挙動の両輪が必要 |
| 多地域適合 | 強い、クレームにリージョンとRunner指紋を載せられる | 中程度、コピーはそのまま拡散 | 中程度、署名は必須だが配布経路が広い |
| 観測性 | issuer、audience、jtiがログに素直に写る | ハッシュ接頭辞と実行者アカウントに留まりがち | 鍵IDと署名対象のフックを自前で足す必要がある |
| 運用コスト | 初期設定は高いがローテーションは安い | 開始は安いが監査と失効が高くつく | 中程度、証明書ライフサイクルは避けられない |
メッシュCIの安全は「緑がたまに出るか」ではなく「セッションがビルドを説明できるか」で決まります。
すでに共有プールを運用しているチームは、この表を設計レビューの添付資料に固定し、Identityが廊下口頭の合意のまま残らないようにしてください。
手順はベンダ中立です。GitHub ActionsでもGitLabでもフィールド名は違うが成果物は同じです。各手順を変更チケットに紐づけ、タスクチェーンの引き継ぎと組み合わせるなら封筒へjob_idとenvironmentを必ず重ねてください。無人Runnerでは更新失敗を黙って飲み込むと長寿命鍵へフォールバックする習慣が定着するため、ページングとゲートを同時に入れます。
六手順は一度に全部入れず、Issuer凍結とAudience分離から着手し、ブートスキャンとSTS交換、TTL上限、失効ドリルを順に積み上げると現場の負荷が分散します。各リージョンで同じ順序を踏むことで、インシデント時の切り分け順序も揃います。
信頼Issuerを凍結:組織管理下のIssuer URLのみ許可し、ワイルドカードホスト名を拒否し、インフラ変更履歴へ差分を残します。
Audienceを環境単位で分離:ステージング、本番、コンプライアンスパーティションごとに別文字列を割り当て、環境横断再利用を禁止します。
Runnerブートを平文スキャンで失敗:PATファイル名やkubeconfigパターンを検出したら登録を中断し、ゴールデンイメージへ戻します。
OIDCをクラウドSTSへ交換:各クラウドの短命セッションパターンに従い、資格情報はメモリ上のファイル記述子へ書き、永続パスへ戻しません。
TTLと更新に上限:セッション長はビルドP95の1.5倍を下回りつつハード上限を設け、更新失敗はページし長寿命鍵へ静かに逃げません。
失効ドリルを定期実施:信頼ポリシーを意図的に一つ落とし、全リージョンで一分以内に新規セッション拒否になるか検証します。
export RUNNER_FINGERPRINT="$(system_profiler SPHardwareDataType | shasum | awk '{print $1}')"
export OIDC_AUDIENCE="vpsmesh-ci-prod-${RUNNER_REGION}"
node scripts/exchange-oidc-for-sts.mjs \
--issuer "${ACTIONS_ID_TOKEN_REQUEST_URL}" \
--audience "${OIDC_AUDIENCE}" \
--runner-fingerprint "${RUNNER_FINGERPRINT}"
注記:STS結果はプロセスメモリまたはtmpfsに保持しジョーンティアダウンで失効させ、交換結果をゴールデンイメージへ書き戻さないでください。
メッシュの価値は都市ごとに同じパイプラインを回すことですが、Identityはリージョン親和とレジストリ外向き方針と同設計にしないと、シンガポールは画像取得が速いのにSTSリージョンが不一致、米国東トークンが東京バケットへ403を返す、といった切り分け地獄が起きます。IssuerとAudienceを最初に疑い、次にRunner指紋をクレームへ載せているか、最後にコンパイラキャッシュを疑う順序をRunbook化すると夜間オンコールの迷走が減ります。
多地域ではDNS、証明書、プロキシの三つがクレーム検証より先に壊れる偽陽性も多いですが、それでもログにjtiと残TTLが無いとクラウド監査ログとの結合ができません。キャッシュ鍵と段階公開へ戻る前に、必ずクレーム表を一枚印刷できる状態にしておくとエスカレーションが速いです。
クレーム優先:repository、environment、refを検証し、再利用ワークフローでパラメータ欠落が無いか確認します。
親和を第二:成果物バケットとレジストリに揃ったSTSリージョンを選び、コンプライアンス許可リストと矛盾させません。
キャッシュは最後:チェックサムと鍵のドリフトが出たらバイト経路へ戻り、Identityが健全でもビルドが壊れるケースを切り分けます。
jtiと残TTLをログへ:jtiをインデックス化しクラウド監査とパイプラインを結合します。
障害ドメイン演習:一リージョンのネットワークを落とし、他リージョンがセッションファイルやtmpfsマウントを継承しないか確認します。
ミューテックスと順序:リース取得の前に資格情報交換を完了し、半端セッションが席を占有しないようにします。
警告:長寿命素材を一時ディスクへ復号して削除してもクラッシュ残渣のリスクが残ります。ジョブ境界で強制破棄できるメモリとカーネルキーリングを優先してください。
以下の三帯は越境するiOSとmacOSパイプライン監査で繰り返し参照された目安であり保証ではありません。自組織のヒストグラムへ差し替え、生分布をアーキテクチャ承認へ添付してください。数値だけを転載して文脈を落とすと現場で再現できない「正しそうな数字」になります。
帯の背後にある前提は、Runnerが常時起電しネットワーク断が短時間で収束すること、ジョブ隔離がコンテナまたはユーザ分離で最低限守られること、監査ログが中央に集約されることです。いずれかが崩れる場合はTTLをさらに短くし、席数と同時に交換頻度のコストを見直してください。
job_id、environment、jtiのいずれか一つ以上と必ず結合し、質問票を閉じられる状態にします。| プラットフォーム | コンプライアンス | レジストリ外向き | 第一選択 |
|---|---|---|---|
| GitHub Actions | 標準 | 公開レジストリ可 | Runnerグループ単位AudienceでOIDCからクラウドSTSへ |
| GitLab | 標準 | プライベート必須 | IdP束縛CI_JOB_JWTと同リージョンキャッシュ |
| 自前スケジューラ | 高 | 外向き制限強い | mTLS分割署名サービス、PATはブレイクグラスのみ |
| フォーク負荷大 | 中 | 混在 | 内部とフォークでAudience分離、共有ワークスペース禁止 |
借り物ノートパソコン、空き時間の誰かのSSH、睡眠とパッチ窓で更新が止まる運用は、監査で求められる隔離と更新周期と相容れません。OIDCが完璧でも無人更新が壊れる設計では再び長寿命秘密へ逃げます。
よくある誤り:対話的利便性だけを最適化し、無人更新とディスク残渣に必要な逆方向の統制を忘れることです。
iOSとmacOSを継続配送しつつOIDCセッションを監査可能フィールドへ揃えたいチームは、調達と複数拠点配線で足止めされがちです。借用ハードウェアでは強制失効と座席隔離を契約に落とし込みにくく、ポリシー議論が観測不能な口約束に寄ります。本番相当のメッシュCIでIdentity境界を回転可能に保ちたい場合、VpsMeshのMac Miniクラウドレンタルが現実的な適合になりやすいです。従量に近い請求サイクル、選択可能なリージョン、契約書に書ける専有ノードがあり、稼働率の議論を測定可能な前提へ戻せます。三年TCOの判断行列と併読し、ローテーション工数まで含めた比較を推奨します。
Runnerグループと環境Audienceを先に固定し、その後でタスクチェーン封筒とリース項目へ揃えます。共有ビルドプールと観測可能タスクチェーンを併読し、リージョンとサイズは価格ページと注文ページで確認してください。
ヘルプセンターから入り、SSHとVNCの比較で遅延とセッション前提を確認します。資格情報が不審ならAudienceとクレーム検証へ戻り、発注前の仕様確認は注文ページも併覧してください。