認可とは何か?あなたに許可される操作を決めるもの
認可は玄関の先にあるゲートです。システムがあなたが誰であるかを把握した後、あなたに何が許可されるかを決定します。
認可はパーミッションを適用することです。認証がアイデンティティを確認した後、認可はそのアイデンティティが特定のリソースに対して特定の操作を実行してよいかどうかを検証します。CI/CDでは、認可はテストパイプラインが本番環境にdeployするのを止めたり、読み取り専用トークンがコードをpushするのを止めたりするものです。
認証と認可
認証は"あなたは誰か"に答え、認可は"あなたは何をしてよいか"に答えます。認証済みであっても、ある操作を拒否されることはあり得ます。優れたシステムはこれらの関心事を分離し、ログイン時だけでなく、あらゆる機微な操作で認可を検証します。
パーミッションのモデル化の方法
- ロールベース: パーミッションをロールに紐づけ、ロールをアイデンティティに割り当てる。
- 属性ベース: ユーザー、リソース、コンテキストの属性に対してルールを評価する。
- アクセス制御リスト: 誰が何をしてよいかをリソースごとに明示的に列挙する。
スコープとトークン
自動化されたシステムでは、認可はスコープを通じてトークン自体に組み込まれることがよくあります。読み取り専用にスコープされたトークンは、たとえ漏洩しても書き込みできません。狭いスコープはCIにおける第一の防御です。パイプライントークンは無人で広い到達範囲を持って実行される傾向があるからです。
パイプラインにおける最小権限
最も安全なデフォルトは、jobに必要なパーミッションだけを付与し、それ以上は付与しないことです。テストだけを実行するworkflowはdeploy用の認証情報を持つべきではありません。たとえばGitHub Actionsでは、GITHUB_TOKENのパーミッションをjobごとに設定できるため、stepはそのタスクが必要とする以上のことはできません。
認可が失敗するとき
広すぎるトークン、内部エンドポイントでのチェック漏れ、誤設定されたロールによる権限昇格などが、よくある失敗です。CIでは、1つの強力な認証情報をあらゆる場所で使い回すのが典型的なミスで、単一の漏洩で攻撃者にすべてを与えてしまいます。
認可とrunner
runnerは、jobが認可されているすべての操作を引き継ぎます。jobのパーミッションを厳しく絞ることで、runnerが侵害された場合の影響範囲を限定できます。エフェメラルで隔離されたrunner(Latchkeyのマネージドrunnerなど)は、job間で認可コンテキストを持ち越さないことで、その範囲をさらに封じ込めます。
重要なポイント
- 認可は、認証済みのアイデンティティが何を許可されるかを統制します。
- ロールベース、属性ベース、ACLの各モデルが、それを表現する一般的な方法です。
- パイプライントークンを最小権限のスコープに絞ることで、漏洩による被害を限定します。