証拠がなければ配布しない
一言でいうと
一覧と署名と証明は、デプロイの直前に読まれなければ存在しないのと同じで、ゲートの価値は、何を止めたかではなく、なぜ止めたかを人が読めるかから生まれます。
なぜ必要なのか
前の3つのモジュールで作ったものは、すべて証拠です。何が入っているかを書いた一覧、このバイト列は私たちのものだという署名、どこから出たかを書いた証明。ところが、証拠は、法廷に提出されなければ何もしません。デプロイの直前にそれを開いてみて、足りなければ止める手順が、ゲートです。
ゲートを作るときに人々が最もよく犯すミスは、署名だけを見ることです。署名の検証は、「このバイト列がこの鍵で署名された」までしか言いません。その鍵が私たちのものか、その署名が付いた証明が本当に私たちのビルダーから出たものか、証明が指す対象が今デプロイしようとしているそのファイルなのかは、それぞれ別に問う必要がある質問です。3つのうち1つでも抜けると、通り抜けられる経路ができます。
どう動くのか
ゲートが投げる質問は、4つにまとまります。
목록이 붙어 있는가 SBOM 이 있고 비어 있지 않은가
서명이 맞는가 우리가 믿는 키로 검증되는가
대상이 같은가 증명의 subject 다이제스트가 지금 이 파일의 해시와 같은가
빌더를 허락했는가 builder.id 가 허용 목록에 있는가
このコードブロックの韓国語の行は、順に、一覧が付いているか(SBOMがあって空でないか)、署名が合っているか(自分たちが信頼する鍵で検証できるか)、対象が同じか(証明のsubjectダイジェストが今このファイルのハッシュと同じか)、ビルダーを許可したか(builder.idが許可リストにあるか)、という意味です。
4行目がよく抜けますが、実務で最も静かに突破されるのが、そこです。署名も合っていて、ダイジェストも合っているのに、そのビルドが誰かのノートPCから出た場合、最初の3つだけを見るゲートは、そのまま通してしまいます。SLSAがBuild L2で専用インフラ上のホスト型プラットフォームを要求する理由が、ここにあります。どこでビルドしたかが、セキュリティの属性そのものだからです(SLSAのセキュリティレベル)。cosignの検証も、同じ方向を見ています。ドキュメントは、cosign verifyが、署名だけでなく署名の証明書が信頼する認証局から出たものかまで確認すると書いています(cosignの検証)。
もう1つ重要な設計上の選択は、理由をコードで残すことです。失敗メッセージを文章だけで出すと、人によって書き方が違い、そうすると「先月、何のために最も多く止まったか」を数えられません。signature_missingやbuilder_not_allowedのような短いコードで残せば、判定がそのまま統計になり、統計があれば、次に何を直すべきかが、議論ではなく数字で決まります。
最後に、ゲートの中にウェイバーの居場所を作っておく必要があります。例外のないゲートは、急ぐときにまるごと切られ、一度切られたゲートは、二度と入りません。例外を記録として残すようにすれば、ゲートは有効なまま残ります。
現場での姿
最もよくある失敗は、ゲートが警告だけを出して止めないことです。パイプラインのログに黄色い行が残り、デプロイはそのまま進みます。最初は「慣れるまで」という理由で始まり、そのうち誰もその行を読まなくなります。止めないゲートは、ゲートではありません。
2つ目は、通る場合を先に確認しないことです。止めるほうから試すと、「常に止める」ゲートも成功したように見えます。正常なリリースが通ることを先に固定して、そのあと止まるべき場合を1つずつ作って初めて、両方向が確認されます。
3つ目は、判定を残さないことです。ゲートが止めたという事実は、その瞬間に画面にだけあり、数週間後に「あのときなぜ止まったのか」と問われても、誰も答えられません。判定と根拠、対象のダイジェストを1行で書いておけば、その質問が、答えられる質問になります。
4つ目は、ゲートを置く位置が遅すぎることです。デプロイの瞬間にだけ検査すると、そのときにはすでにリリースが予定されていて人が集まっているので、止まった瞬間に、ゲートを切ろうという話が出ます。同じ検査をビルドの直後にも1回動かせば、問題が数時間前に表に出て、デプロイ直前の検査は確認に近いものになります。同じプログラムを2か所から呼ぶだけなので、コストもほとんどかかりません。
5つ目は、ゲートが見る証拠をゲート自身が作ることです。デプロイの直前にSBOMを作り直して検査すると、その一覧は、ビルドが実際に使ったものではなく、今もう一度展開したものです。2つが食い違う日こそ確認したかった日なのに、その食い違いが見えなくなります。証拠は作った側が付け、ゲートは読むだけにする必要があります。
6つ目は、ゲートを有効にする順序です。最初から4つの検査を一度に強制で動かすと、既存のリリースがすべて止まり、その日にゲートが切られます。実務で生き残る順序は、理由だけを記録する期間を短く置き、どの理由が何件出るかを数字で見たあと、1つずつ順番に強制に切り替えることです。このときも、「いつまでにすべて強制に切り替える」という日付を一緒に固定する必要があります。日付がなければ、記録だけの期間が永遠に終わりません。
次のラボですること
リリースのバンドルに来歴証明を付けて署名し、4つを確認して、理由コードとともに止めるゲートを作ります。正常なバンドルが通ることを先に確認したあと、署名がないバンドル、アーティファクトが変わったバンドル、署名は合っているが許可していないビルダーが作ったバンドルの3つを自分で作って、それぞれ別の理由で止まることまで確認し、その判定を監査記録として残します。