同じアカウント名と異なる認証情報
一言でいうと
権限の取り消しは、できることを変え、サービスアカウントのUIDの変更は、古いトークンが指す身元を変えます。 同じ名前でアカウントを再作成しても、古いトークンと既存のRoleBindingが同じ方式で扱われるわけではありません。
なぜ必要なのか
例とする状況です。readerのトークンが露出したという連絡を受けました。運用者がアカウントを削除して、 同じ名前で作り直し、古いトークンの401を見て、対応を終えました。ところが、新しいトークンで 取得すると、以前と同じデータが見えます。トークンの取り消しに失敗したのでしょうか。
早まって結論を出す前に、何を削除し、何を残したのかを確認する必要があります。アカウントは新しく 作成しましたが、その名前を対象とするRoleBindingはそのままかもしれません。新しい身元に 再び権限が結び付く現象を理解して初めて、インシデント対応の終了条件も正確に決められます。
どう動くのか
同じ名前、異なるUID
今回の実験は、既存のPodとRoleBindingを残して、SAだけを再作成します。元のトークンのsubは system:serviceaccount:kcsa-identity:readerです。新しく発行したトークンも、subは同じです。 しかし、2つのトークンのサービスアカウントのUIDは違います。人間の目に見える名前だけを比較すると、 異なるオブジェクトを同じオブジェクトと勘違いしかねません。
プローブでは、既存のトークンが期限切れになる前にSAを再作成しました。TokenReviewの認証結果は falseになり、APIの取得は401になりました。expと観測した時刻をあわせて残したので、 単に長く待ってトークンが期限切れになった結果と区別できます。既存のPodのUIDもあわせて 確認し、Podを新しく作成した影響として説明しないようにしました。
バインディングはどの主体を指しているか
RoleBindingのServiceAccountの主体は、名前とネームスペースを使います。今回のバインディングは、 kcsa-identityのreaderを指しています。SAの古いUIDを保管して、そのオブジェクトだけを永久に許可する 構造ではありません。次のように結果が変わる理由を、各列で説明してみてください。
| 状態 | 古いトークン | 新しいトークン | バインディング |
|---|---|---|---|
| 元のアカウント、最小限の読み取り権限 | 自分のConfigMap 200 | まだない | 元のバインディングが存在 |
| Roleのrulesを空にする | 認証true、取得403 | まだない | そのまま存在 |
| Roleを復元したあとSAを再作成 | 認証false、取得401 | 発行すれば取得200 | 同じ名前を指し続ける |
| バインディングを削除 | 引き続き401 | 認証true、取得403 | 削除された |
この表は、今回の個人クラスターの実際の観測を学習用にまとめたものです。新しいトークンの200は、 古いトークンが復活した証拠ではありません。新しいUIDを持つ認証結果と、名前に基づく認可が 組み合わさった結果です。また、バインディングを削除したあとの403は、新しいトークンが無効になったという意味ではありません。 認証は引き続きtrueだという別の観測が、この解釈を裏づけます。
削除するときも名前だけを信じない
削除対象の現在のUIDを読み、基準線と比較したあと、UID・resourceVersionの前提条件付きで 削除をリクエストします。調査している間に誰かがオブジェクトを入れ替えていたなら、別のオブジェクトを削除する代わりに 止めて、再確認する必要があります。今回のヘルパーの目的は、元のアカウントとバインディングだけを変更することであり、 名前が同じだからといって、あとから生じた別のオブジェクトまで削除することではありません。
現場での姿
インシデント対応では、まず露出した認証情報、使用できるAPI、接続されたワークロード、ほかのバインディングを あわせて調査します。SAの削除は、そのアカウントを使うほかの作業にも影響を与えかねません。 この実験の削除・再作成を、そのまま本番にコピーしないでください。最小限の権限の取り消し、業務の中断範囲、 認証情報の再発行と再デプロイ、再露出の原因の除去を調整したうえで、終了条件を確認する必要があります。
ほかのチームのリクエストも一緒に送る理由もあります。自分のリクエストの拒否だけを確認すると、クラスター全体を 壊しても成功に見えかねません。今回は、別のネームスペースのreaderの認証UIDと、 合成ConfigMapのUID、正常な200のレスポンスがそのままかを確認します。これはこの2つのネームスペースの 影響範囲の検証であって、プラットフォーム全体の分離や、すべてのユーザーの業務が中断しないことの証明ではありません。
オフラインでのJWT検証とオンラインでの検査も区別します。署名と有効期間をローカルで確認するサービスは、 バインドされたAPIオブジェクトがいまも存在するかを、ひとりでには知りえません。現在のバインド状態が重要なら、 TokenReviewのようなオンラインでの検証が必要です。逆に、今回の単元のクレームのデコードは、オフラインでの 署名検証の実装ではないので、両方の方式を実装して比較したと報告してはいけません。
削除待ちのオブジェクトの猶予のルールと、すでに消えた、またはUIDが変わったオブジェクトの検査を混同しません。 今回は、実際のUIDの変更とAPIの結果をあわせて観測しました。決まった時間だけ眠ってから 成功として処理する方式では、身元の切り替えの証拠を残せません。
次のラボですること
権限を空にしてから復元し、正確に元のSAを同じ名前で再作成したあと、新しいトークンを発行します。 最後に、元のバインディングだけを取り消して、古いトークンの401・新しいトークンの403・ほかのチームの200を区別します。観測のたびに、 時刻・UID・認証結果・HTTPステータスを残し、過去に成功した記録と現在の状態を分けて解釈してください。 前のステップのファイルを消して記録を合わせるのではなく、何がいつ変わったのかを説明することが課題です。