itB!HatenaPocketLINELINEプラットフォーム技術部の小林正彦です。本記事では「わかるようでよくわからないポリシー」のお話をしていきたいと思います。AWSの公式ドキュメントにはポリシーに関する膨大な情報が掲載されています。それらの内容を机上で整理して理解するのは難しいです。「どういう場合にどのポリシーを定義するとよいのか」「それらを適用する上での注意点は何か」をつかめていないと、がんばって実装してみたのにメンテナンス困難なポリシー設計になってしまったなんてことになりかねません。いった事態に陥らないために「どういう場合にどのポリシーを定義するとよいのか」、「それらを適用する上での注意点は何か」を整理していきますが、すべてを解説しようとするととんでもない量になってしまうので本記事では「タイプの違い」に注目してポイントを記載していきます。ポリシーの基礎的な話からまとめていきますので、これからポリシーを触り始める方にも、すでにポリシーを理解している方にも参考になれば幸いです。ポリシーとは何でしょうか。アクセス管理を行うための「IAM」サービスの機能です。その回答の裏で重要な観点が漏れているかもしれません。AWSが提供するポリシー機能とは、IAMサービスが扱う「ユーザー」を対象としたアイデンティティ管理及びアクセス管理だけに留まらず、「もの」である各種サービスリソース間のアクセス管理までも含まれます。ユーザーだけに注目していては不十分ということです。ポリシーを3行でポリシーとは何かを3行で。アイデンティティやリソースにアタッチしてアクセス許可を定義するJSONドキュメントアクション実行のリクエスト内容とポリシー定義を評価してアクセス許可or拒否を判断6つのタイプがあるポリシーのタイプ3行目に書いた「ポリシーには6つのタイプがある」についてですが、AWSは用途に応じて異なるタイプのポリシーを提供しています。それら6つのポリシータイプと用途を、使用頻度で階層化した図がこちらです。下層になるほど利用シーンが限定されていくので「階層の深さ」が「実現したいセキュリティポリシーの強度」に直結します。一般的には上から2番目までのポリシータイプを使用します。3階層目以降のポリシーを使えばより細かなアクセス制御を実現できます。2層目までで定義した許可範囲をさらに制限したい、あるいは、特別なリソースに対してアクセス許可を付与したいといった高度な設定を実現する場合に使用できますが、複数のタイプを併用するとそれだけポリシーの評価方法が複雑になり管理者(というか人間)が実態を把握できなくなってしまうかもしれません。きめ細やかなアクセス制御の実現と管理作業の負荷はトレードオフであることを理解して、適切なレベルのアクセス管理を行いましょう。冒頭に述べた「ポリシーとは」の回答が正解かどうかは、回答者がどの階層まで意識しているかによると思います。リソースベースポリシーまで使用するべきなのにアイデンティティベースポリシーの層までしか理解していないとすれば、適切なポリシー設計ができません。以降では、1階層目の「アイデンティティベースポリシー」と2階層目の「リソースベースポリシー」に焦点を当てて、それぞれの性質・考慮点を記載していきます。3階層目以降のタイプの詳細な説明はポリシーとアクセス許可の内容を参照してください。アイデンティティベースとリソースベースを比較まずは両ポリシーの特徴を簡単にまとめます。「誰がどのリソースに対してどんなアクションを実行できるか」を指定します。AWS管理ポリシー、カスタマー管理ポリシー及びインラインポリシーを用いてポリシーを定義し、IAMアイデンティティ(=ユーザー/グループ/ロール)に「直接アタッチ」して使います。「このリソースに対して誰がどんなアクションを実行できるか」を指定します。誰(=プリンシパル(依頼者)エンティティ)がどんなアクションを実行できるかを指定したポリシーを作成し、リソースにアタッチします。リソースにアタッチすると、ポリシーの中で指定した誰(=プリンシパルエンティティ)に対してアクセス許可が付与されます。両者を下記の3つの観点で比較してみます。アタッチ先・・・作成したポリシーを何に紐づけるかアクセス許可の付与先・・・アクセス許可を何に与えるか作成方法・・・ポリシーをどこに定義するかアイデンティティベースとリソースベースをこれらの観点で下表に整理しました。ここから、2つのポリシーの違いについて説明します。アタッチ先とアクセス許可の付与先まず1つ目は、アイデンティベースとリソースベースとではポリシーのアタッチ先とアクセス許可の付与先が異なるという点です。アイデンティティベースポリシーの場合は、アタッチ先とアクセス許可の付与先が同じです。「あるユーザーにアイデンティティポリシーをアタッチしたら、アタッチしたそのユーザーにアクセス許可が付与される」ということです。リソースベースポリシーの場合はアタッチ先とアクセス許可の付与先が異なります。付与先が異なるとはどういうことか、S3を例に説明します。S3のリソースにはバケットが該当します。リソースベースポリシーのアタッチ先はリソースなので「S3のバケットにリソースベースポリシーをアタッチする」ということです。※1しかしながらアクセス許可の付与先はバケットではありません。アクセス許可の付与先は「リソース」ではなく「プリンシパル」です。他アカウントのユーザーまたはアプリケーション」ですので、バケットにアクセスしてくるエンティティにアクセス許可を与える。アタッチ先とアクセス許可の付与先の違いを簡易な図で表してみます。S3バケットにアタッチするリソースベースポリシーのことを「バケットポリシー」と呼んでいます。名称は異なりますが実態は同じものを指しているので、別のポリシーであると勘違いしないようにしてください。リソースベースポリシーを別の名称で呼んでいる他の例として、IAMロールにアタッチする信頼ポリシーがあります。リソースベースはインラインポリシーのみつづいて2つ目の違いは、リソースベースポリシーはインラインポリシーしか作成できないという点です。インラインポリシーしか作成できないということは「テンプレートとなるAWS管理ポリシーが用意されていない」ということです。いちから定義を作成しなければなりません。リソースベースという名前の通りでリソースにポリシーをアタッチするので「リソースベースポリシーはインラインポリシーしか作成できない=リソースごとにポリシーをいちから作成する」ということです。SQSのリソースベースポリシー作成を例に説明すると、SQSでのポリシーを定義する単位は「キュー」です。マネジメントコンソールあるいはCLIコマンドでキューごとにポリシーを作成します。利用しているキューの数が少ない場合はそれほど面倒な作業ではないと思いますが、数十・数百とキューが増えたときに1つ1つベタ書きしていく作業の煩雑さは想像に難くありません。SQSの場合はポリシー作成を支援するエディター[※2]が用意されているのでエディターの画面に従ってアクションや条件の要素を選択していけば作成できますが、リソースごとに同じ作業をくり返すことに変わりありません。ロールをアタッチするように複数のリソースでポリシーを共有できる構成だと楽だな、と、思います。エディター上で条件(Condition)を選択できますが、すべてのCondition要素が選択肢として用意されているわけではありません。選択肢に存在しないCondition要素を使用したい場合はJSONドキュメントを作成する必要があります。アイデンティティベースとリソースベースの併用ここまで両ポリシーを対比させてきましたが、アイデンティティベースポリシーとリソースベースポリシーを併用する場面を検討してみます。冗長な書き方をすると「アイデンティティベースポリシーをアタッチしたアイデンティティエンティティ(がアタッチされたリソースも含む)から、リソースベースポリシーをアタッチしたリソースに対して任意のアクションを実行する」ということです。具体的なアクセスケースとして下図のような場面を設定します。Lambda)がS3にアクセスする構成です。アクセス元のエンティティにはアイデンティティベースポリシーを定義、アクセス先のエンティティ(S3)にはリソースベースポリシーを定義します。ユーザーからS3へのアクセスあるユーザーがマネージドコンソールを操作して、S3に対してアクションを行う。実行可能なアクションはユーザーにアタッチしたポリシーに定義したアクションのみを想定。EC2からS3へのアクセスインスタンス上でAPIリクエストを実行し、S3に対してアクションを行う。実行可能なアクションはアイデンティティベースポリシー(をアタッチしたロール)に定義したアクションのみを想定。EC2それ自体はアイデンティティエンティティではないのでアイデンティティベースのポリシーをアタッチできませんが、アイデンティティベースのポリシーにアタッチされたロールを介して、EC2をアイデンティティエンティティのように扱うことができます。LambdaからS3へのアクセス他サービスのイベントをトリガーにLambdaを起動し、S3に対してアクションを行う。実行可能なアクションはアイデンティティベースポリシー(をアタッチしたロール)に定義したアクションのみを想定。CLI経由でリソースベースポリシーを定義できます。マネージドコンソールからトリガーとなるサービスを指定した場合は、自動的に適切なサービスロールが割り当てられるので通常はポリシーの内容を意識する必要はありません。ポリシー設計のポイントさきほどの図のアクセスケースの場合、両ポリシーの内容はどのように評価されるでしょうか。アカウント構成サービス間のアクセスが同一アカウント内アクセスであるか、クロスアカウントアクセスであるかによってポリシーの評価方法が異なります。クロスアカウントアクセスである場合AアカウントとBアカウントが連携するクロスアカウント構成を想定します。AアカウントのEC2からBアカウントのS3に対して特定のアクションのみを許可したい場合は、AアカウントEC2のアイデンティティベースポリシーに「BアカウントS3へのアクション許可」を定義し、かつ、BアカウントS3のリソースベースポリシーに「プリンシパルをAアカウントに指定して同じアクションを許可」する定義が必要です。両アカウントで明示的なALLOWを定義しないとアクションは許可されないということです。どちらか一方にのみ定義しても許可されません。同一アカウントアクセスである場合Aアカウント内で閉じた構成を想定してみます。同一アカウント内でEC2からS3へアクセスをする場合は、アイデンティティベースとリソースベースの両ポリシーによって付与されているすべてのアクセス許可を合わせて評価します。どちらか一方のポリシーにALLOWの定義があればもう一方のポリシーにアクション許可を定義しなくてもよいということです。アイデンティティベースを先に評価して、次にリソースベースを評価するといったように順次評価していくのではなく、両方をあわせて一緒に評価するという動きです。不要なポリシー定義が後々悪影響を出して混乱しないように、アクセス元/先が同一アカウントか、クロスアカウントであるかを確認して極力シンプルな設計になるように注意しましょう。明示的なDENYの必要性クロスアカウントアクセスである場合は、どちらか一方のALLOWの定義を削除すればリクエストは拒否されるという評価をする仕様なので明示的なDENYは必須ではありません。同一アカウントアクセスである場合は、アクセス元/先サービスのどちらか一方にALLOWを定義すると、意図しないアクセスまで許可されるリスクが生じます。アクセスを受ける側が想定していないアクセスであっても、アクセス元のアイデンティティベースポリシーにALLOWを定義すると許可されてしまうのです。このリスクを防ぐには明示的なDENYをリソースベースポリシーに定義しなければなりません。明示的なDENYを使用する際に注意するのが評価の順序です。明示的なDENYはすべてのALLOWに優先して評価されます。そのため、通したいリクエストがALLOWになるように、通したいリクエスト以外のすべてのリクエストを明示的にDENYするポリシーを定義しなければなりません。明示的なDENYを使用する場合のポリシーのイメージを以下に示します。図中の実線が通したいリクエスト、灰色四角が明示的なDENYを表しています。バケット側では通したいリクエスト以外はすべて明示的にDENYするようなリソースベースのポリシーを定義します。「ユーザーAのXXXXアクション」でも「InstanceのYYYYアクション」でも「LambdaのZZZZアクション」でもないリクエストはすべて拒否、というような複雑な論理式の設計が必要です。明示的なDENYのAND/ORを組み合わせることで上図のような要件を満たすことはできるのですが、設計そのものが非常に複雑であり管理者に高い経験値が要求されることや、設定ミスによる影響[※3]を考慮すると明示的なDENYを使用したアクセス制御は推奨しません。明示的なDENYを適用する範囲を誤ると「通したいリクエストが通らない」、「通したくないリクエストが通る」という状況になり、該当サービスを設計意図どおりに管理できなくなる恐れもありますので十分にご注意ください。職務機能とポリシーについてポイント1,2で説明した内容はポリシーの仕様に関する話です。ここでは「ポリシーの仕様」とは別の観点として「職務機能とポリシーの関係」について簡単にまとめます。職務機能とは「誰がどのような役割でどのようなタスクを実行できる権限を持つかを整理したルール」であり、一般的に「ロール」と呼ばれるものと言えます。閲覧者専用ユーザー」などの役割を用意し、役割ごとの権限を定義したポリシーを作成しています。この「役割と権限」のルールをまもるためにポリシー/ロールを使用します。ここで述べている役割をあたえられる「誰が」とは、操作をするユーザーだけではなく各種リソースにアクセスを行うAWSサービスなどの「もの」も指しますのでS3やLambdaも該当します。ポリシー設計のポイントで記載したアクセスケースでのアクセス元がその例です。そもそもの話として「ユーザー」や「もの(サービスリソース)」にどのような許可を与え、どのようなリスクから保護する必要があるか、といったルール(役割と権限の関係)がきちんと整理されていないと、必要なポリシーを定義しようがありません。明確なルールがあってはじめて、ポイント1,2で書いたような仕様を踏まえた適切なポリシーが定義できるのです。誰がどの範囲まで管理するのか、それがアカウント単位か、ネットワーク単位か、サービス単位なのか。API処理)をどこまで許可するのか、参照だけか、削除も許可するか。他者が管理しているリソースを使いたい場合に、そのリソースの管理者と利用者の両者の合意が必要か、あるいは利用者は任意にリソースを使用してよいかなどのルールを整備しましょう。まとめポリシーの基本的な情報と、設計のポイントを述べてきました。繰り返しになりますが要点を記載します。AWSが提供するポリシー機能のごく一部にしか触れていませんが、この範囲だけでもシステム適用とその後の管理が大変であることは想像できると思います。したルールを定めず場当たり的にポリシーを作成した結果、管理業務がどんどん煩雑化していく泥沼に陥らないように、ポリシー設計の初期段階からルールの明確化と標準化を心がけましょう。masahiko-kobaこのサイトの掲載内容は投稿者自身の見解であり、必ずしも当社の立場、戦略ならびに意見を代表するものではありません。本サイトに掲載されている商品またはサービス等の名称は、各社の商標または登録商標です。アークシステムのSNSをいいね!&フォローしよう。@arksystemsJp最新情報をお届けします。この記事が気に入ったらいいね!&シェアお願いします。Manager】OSパッチ適用を自動化しよう非常に対応工数を必要とするOSパッチ適用運用を自動化する方法を紹介します。...2024年1月30日Zabbixの予兆監視を使えるようになろうZabbixを利用して障害の予兆監視をする方法を紹介します。...2023年12月26日ZabbixのアラートでRedmineのチケットを自動起票する方法ZabbixとRedmineの連携方法を紹介します。