ポリシーリスクを可視化。自然な言葉でポリシーに関する疑問を解決します。 デモを申し込む →

Published:

AWS Permission Boundaries for Dummies

by Mark Byers

AWS のアクセス許可境界(permission boundary)は分かりにくいものです。分かりにくいと言えるのは、私自身が混乱し、理解するまでに数年かかったからです。もう一つの理由は、Corey Quinn 氏がそう述べ、誰か分かりやすく説明してほしいと求めていたからです。

コンテナ化アプリケーション向け CLI である AWS Copilot に、IAM のアクセス許可境界などが追加された。いつか誰かが、ごく簡単な言葉で IAM のアクセス許可境界とは何かを説明してくれないだろうか。今日こそは?

うまくいかないかもしれませんが、やってみます。

要約:通常の IAM ポリシーは、操作を許可することも、操作を禁止することもできます。アクセス許可境界は、操作を禁止することしかできません。 主な用途は、誰かに IAM の一部を管理させつつ、(本人または他者の)権限昇格ができるほどの範囲は与えない、というものです。いわばフェイルセーフです。 アカウント内で誰かに IAM を管理させ、かつ権限昇格をさせたくないのであれば、ほぼ必ずアクセス許可境界が必要です。

AWS の公式ドキュメントには詳細な説明がありますが、それでもやはり分かりにくいところがあります。本記事は、(一点の例外を除き)書き方の細部を解説するものではなく、概念とその存在理由を理解していただくためのものです。

素人扱いではなく小学生に説明するつもりで、もう一度解説してほしい

承知しました。それではご説明します。

IAM のアクセス許可境界が登場する以前は、自分の担当範囲の IAM 権限を誰かに管理させつつ、EC2 インスタンスや本人自身などに過剰な権限を与えてセキュリティ上の問題を生じさせない、ということが非常に困難でした。特に問題になったのは、IAM ポリシーを作成させ、それを割り当てさせたい場合です。これは権限委譲による管理の課題です。つまり「IAM に関する一部の事項は管理させるが、それ以外は管理させない」という問題です。

これは非常によくあるシナリオです。開発者は、自分のアプリケーションスタック内のインスタンス、Lambda 関数、コンテナタスク用にロールを作成し、そのロールに権限を割り当てることがよくあります。インスタンスに S3 バケットからデータを読み取らせるといった単純なものかもしれません。しかし、セキュリティの観点からは、これは扱いが難しい問題です。

  • 開発者に独自のポリシーを書かせると、*.* のような過剰な権限を追加される可能性があります。
  • 開発者にポリシーを割り当てさせると、権限が過大な既存ポリシーをアタッチされる可能性があります。
  • 開発者に新しいロールの作成とポリシーの割り当ての両方を許可すれば、同じ問題が生じます。

もちろん、これらすべてをセキュリティ担当者や上位の管理者が行うこともできますが、効率的ではありません。アクセス許可境界を使えば、IAM 管理者を 2 階層に分けられます。すなわち、全体のセキュリティ責任を負う上位の管理者と、日常的な作業を行う下位の管理者です。

アクセス許可境界とは、ある人または対象が持ちうる最大の権限を列挙した IAM ポリシーにすぎません。このポリシーをアタッチしておけば、その対象を管理する開発者は、境界で許可された範囲を超える権限を与えることが決してできません。さらに、開発者に新しいロールやユーザーの作成と権限の割り当てを許可したうえで、作成するものすべてにそのアクセス許可境界を付与するよう要求することもできます。これにより、意図した範囲を超える権限を持つものを作成したり変更したりすることが不可能になります。

小学生向けとは言い難いが、例を挙げてもらえないか

Alice は、ある AWS 組織のスーパー管理者です。数百のアカウントを統括しており、各アカウントには実際のアプリケーション構築を担当するローカル管理者と開発者がいます。

Bob はそうしたローカル開発者の一人です。Bob は新しいアプリケーションを構築しており、自分のアプリに必要なものを把握しているため、自分でロールとポリシーを作成する方が効率的です。

Alice は、Bob に自分のアプリケーションの一部について IAM の管理を任せることにしました。具体的には次のとおりです。

  • Bob は、自分のインスタンスや Lambda 関数に必要な権限を持つ新しい IAM ポリシーを作成し、割り当てることができます。
  • アカウント内では、これらのコンポーネントが決して触れてはならない他の AWS サービスも利用されています。そのため、サービスコントロールポリシーで単純に無効化することはできません。それを行うと、利用が認められているコンポーネントでもそれらのサービスが使えなくなってしまいます。
  • Bob は、自分自身に新しいポリシーを割り当てることはできません。

これは典型的な権限委譲による管理のケースです。Bob には IAM の一部のみの管理が認められています。 まさにこうした場面でアクセス許可境界を使用します。

  • Alice は、Bob のインスタンスと Lambda 関数が通信できる AWS サービス(S3、SNS、SQS など)への権限を許可するアクセス許可境界「A」を作成します。
  • Alice は、Bob が IAM ロールとポリシーを作成・割り当てできる一方で、自分自身には割り当てられないようにするアクセス許可境界「B」を作成します。
  • Alice は、Bob に新しいロールとポリシーを作成・割り当てする IAM 権限を与えますが、新しいロールにはすべて「A」のアクセス許可境界を付与することを必須とします。これにより、それらのインスタンスや Lambda 関数が境界を超える権限を持つことは決してなく、それ未満の権限に留めることはできます。
  • Alice は、Bob が自分自身に権限を割り当てられないようにするため、アクセス許可境界「B」を Bob に割り当てます。これにより Bob は、「A」を付与したうえでデプロイするという要件を解除できなくなります。

この課題への対処法は複数ありますが、要点を言えば、アカウント内で誰かに IAM の一部を管理させたい場合、過剰な操作をさせたくないのであれば、おそらくアクセス許可境界が必要になります。

ここでサービスコントロールポリシーが使えない理由をもう一度知りたい

SCP で対応できる場合もありますが、SCP を使えるのは組織(Organization)に属している場合に限られるのに対し、アクセス許可境界はどのアカウントでも機能します。また、SCP は実行可能な API 呼び出し(ひいては利用できる AWS サービス)を制限するといった用途には非常に適していますが、この種の粒度や条件指定を想定したものではありません。

前述の例を考えてみてください。Alice は、アカウント内のサービスへのアクセスは許可しつつ、Bob が作成したリソースからのアクセスは許可しないようにするために、リソース識別子を把握しなければならないかもしれません。これに対処する方法(リソースパスの利用など)はありますが、アクセス許可境界の例より簡単になるわけではなく、サポートされている条件キーによっては常に機能するとは限りません。

私のインシデントレスポンス訓練環境では、アカウント内の管理者ユーザー(受講者)が組織レベルのアクセスやその他いくつかの設定を壊せないよう、SCP を使って制限しています。ただしこれが機能するのは、受講者に IAM の全権限を与えており、彼ら自身がすでにスーパー管理者の一人だからです。過剰な権限を持つリソースの作成を制限したいのであれば、アクセス許可境界か、あらかじめ用意したポリシーのみを割り当て可能にする SCP が必要になります。

拒否ポリシーだけでは済まないのか

実質的には無理です。アクセス許可境界が存在する以前に試しましたが、複雑さもさることながら、抜け道があまりにも多くありました。

もう一つ簡単な例を挙げてほしい

もちろんです。当社自身が使っている例をご紹介します。

一部のお客様は、当社が自社アカウント内で IAM の変更を行うことを許可しています。これにはクロスアカウントロールを使用します。お客様がそのロールをデプロイする際、当社が自分自身の権限を変更できないようにするアクセス許可境界を適用します。これにより権限昇格を防止します。

理解できた気がするが、これらの IAM ポリシーはどのように相互作用するのか

ポリシー評価ロジックについては AWS のドキュメントをご確認ください。以下は私のメモです。

  • サービスコントロールポリシーは、アカウント内で誰もが実行できる操作を制限します(サービスの有効化・無効化など)。
  • IAM のアクセス許可ポリシーは、ユーザーとロールがアカウント内で操作を行うことを許可します。
  • IAM のリソースポリシーは、ユーザーとロールが、そのポリシーがアタッチされたリソースを操作することを許可します。
  • アクセス許可境界は、ユーザーまたはロールが持ちうる最大の権限を設定します。操作を許可することはできませんが、操作を禁止することはできます。

これらのポリシーはすべて組み合わさって機能します。 ある操作を実行するには、スタックのいずれかの層にその操作を許可する権限があり、かつどこにもそれを妨げる拒否ポリシーが存在しない必要があります。 どこにあるものであれ、Deny が 1 つでもあれば、あらゆる Allow を上書きします。

アクセス許可境界を使うべき場面をもう一度確認したい

アカウント内で誰かに IAM の一部を管理させたいが、その範囲は制限したい。そう考えたときこそ、アクセス許可境界を検討すべき場面です。

当社の新しいFireMon Authorization Controlのような高度な IAM ツールを利用している場合でも、特に機密性の高いアカウントでは、アクセス許可境界が必要になることがあります。

含めるとおっしゃっていた1つの例とは

アクセス許可境界は特定の操作を防ぐためのものですが、許可するすべてのアクセス許可を指定する必要がある点は変わりません。つまり、そのユーザーまたはロールに実行させたくない1つの操作をブロックするために DENY ステートメントを含むアクセス許可境界を記述した場合でも、ALLOW * ステートメントがなければ、そのユーザーやロールは何も実行できません。

私も最初はこの点で混乱しました。Amazon の説明を読み違え、アクセス許可境界を使えば単にアクションをブロックできると考えていたためです。確かにブロックはできますが、本日は触れないリソースポリシーのユースケースを除き、アクセス許可境界には許可したいものもすべて含める必要があります。アクセス許可境界で1つを DENY し、通常の IAM アクセス許可ポリシーで他を ALLOW する、という形では機能しません。アクセス許可境界にも ALLOW ステートメントが必要です(そして、私は手を抜いてここでは ALLOW * を使うこともあります)。

まだ分かりにくい場合

お気軽にメールをお送りください。実際のところ、この仕組みは本当に分かりにくいものです。

AWS Permission Boundaries for Dummies - www.firemon.com