TT Lab
はじめる
学ぶ 学習パス コース

クラウド権限設計

アクセスキーが漏れる理由は、存在するからだ

TT Labで続きを見る

一言でいうと

長期のアクセスキーは、作らないのが最善です。ロールを引き受けて受け取った一時的な資格情報は、数時間後に自分で期限切れになるので、漏れても、被害が時間で区切られます。

なぜ必要なのか

GitHubの公開リポジトリにAWSのキーがコミットされる事故は、今も毎日起きています。ボットが数分で見つけ出して、暗号資産のマイニング用のインスタンスを起動します。請求書は数千万ウォン単位で届きます。

ここで本当の問題は、コミットのミスではなく、そのキーが存在していたことです。長期のキーには、次の性質があります。

どう動くのか

ロールを引き受けるということ

ロールは権限のまとまりで、信頼ポリシー(trust policy)が、「誰がこのロールを引き受けられるか」を決めます。

{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Service": "ec2.amazonaws.com" },
    "Action": "sts:AssumeRole"
  }]
}

このロールは、EC2インスタンスが引き受けられます。インスタンスに付けておくと、その中で動くプログラムがキーなしで資格情報を得ます。メタデータサービスから自動で受け取り、期限切れの前に自動で更新されます。

まとめると、次のとおりです。

長期のアクセスキー ロール(一時的な資格情報)
有効期限 なし 通常1–12時間
配布 ファイル・環境変数でコピー 自動で注入
取り消し 手動で探して取り消す 期限切れを待てばよい
追跡 誰が使っているか不明 ロール単位で監査ログ

サービスアカウントのキーも同じ問題

Kubernetesでも同じです。Podにクラウドのキーを、Secretとして入れる方式は、同じ危険をそのまま抱えます。代わりにOIDCフェデレーションを使います。クラスターが発行したサービスアカウントトークンで、クラウドのロールを引き受けます(AWSのIRSA、GCPのWorkload Identity、AzureのWorkload Identity)。キーがそもそも存在しなくなることが核心です。

CIも同じです。GitHub ActionsやGiteaのランナーに長期のキーを入れる代わりに、OIDCでロールを引き受けさせれば、リポジトリのSecretからクラウドのキーが消えます。

それでも長期のキーが必要なとき

完全になくせない場合があります(外部SaaS連携など)。そのときは、最低限、次のようにします。

  1. 専用のプリンシパルを作ります。人のアカウントのキーを共有しません。
  2. 権限をその用途だけに絞ります。Conditionで、IPや時間まで。
  3. 定期的なローテーション(rotation)を手順にします。カレンダーに入れます。
  4. 使用の痕跡を見ます。最後に使われた時刻が古ければ、削除します。

4つ目が最も安上がりで、効果が大きいです。使っていないキーを削除するだけで、攻撃面が大きく減ります。

セッションと有効期限

ロールを引き受けるときに、セッション時間を決めます。短いほど安全ですが、短すぎると、長い作業の途中で期限切れになります。実務の基準は次のとおりです。

現場での姿

ロールを引き受けるときに気をつけること

ロールが長期のキーより安全なのは確かですが、信頼ポリシーを緩く書くと、その安全がまるごと消えます。事故が起きる場所は、たいてい決まっています。

誰でも引き受けられるように開けておいたロール。信頼ポリシーのプリンシパルを広く書くと、別のアカウントの誰かが、そのロールを引き受けられます。外部の協力会社に権限を与えようと開けておいたものが代表的で、相手のアカウント番号だけでは足りません。そのアカウントの中の誰でも引き受けられるからです。外部に開けるときは、双方だけが知る識別子を条件として一緒にかけ、第三者がそのアカウントを経由して迂回できないようにする必要があります。

フェデレーションで条件を抜かすこと。CIがOIDCでロールを引き受けるとき、どのリポジトリのどのブランチかを条件にかけないと、そのCIサービスを使うどのリポジトリでも、こちらのロールを引き受けられます。これが最もよく出るミスで、条件1行で防げます。

ロールを渡す権限。リソースを作るときに、そのリソースにロールを付ける操作は、実質的に、「自分にはできないことを代わりにやらせられる」権限です。この操作を与えるときは、どのロールを付けられるかまで絞る必要があり、そうしないと、低い権限のユーザーが、管理者ロールを付けたリソースを作って、権限を引き上げられます。

チェーンの終わりを見ます。ロールが別のロールを引き受け、それがまた別のロールを引き受ける構造ができると、最終的に何ができるのかを、人が追跡しにくくなります。前のモジュールで述べた評価ツールが、ここで特に役立ち、チェーンの深さをルールで制限しておくことも方法です。

最後に、一時的な資格情報も、有効なあいだは取り消されません。ロールの権限を減らしても、すでに発行されたセッションは、そのまま生きています。そのため、セッション時間を短くすることは、単なる衛生ではなく、事故が起きたときの対応速度そのものです。

次に見ること

権限を実際に絞っていく順序。最初から最小権限を当てることは不可能です。