綺麗なIAMポリシーを書きたくて

# はじめに
この記事は [NTTテクノクロス Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ntt-tx) シリーズ2 12/8の記事です。

NTTテクノクロスの木村です。
普段はAWSを活用したWebアプリ/インフラ開発の業務に携わっております。

本記事は**IAMポリシーの作り方**をテーマとした記事です。
年末ということでAWSリソースの掃除・棚卸をする中で、過去に作成したポリシーを確認していたところ、
「このポリシーは何がしたいのか」
「セキュリティ面は問題ないだろうか」
など、作成したポリシーの品質の低さにしょんぼりすることがありました。
ふと振り返ると、IAMポリシーの基本構造やチェック方法についてしっかりと整理してこなかったと思い、IAMポリシーを作成するにあたり意識すべきことや役立つサービスをまとめてみました。

# 目次
1. [文法に準拠する](#1.文法に準拠する)
2. [機能を満たす](#2.機能を満たす)
3. [セキュリティ対策](#3.セキュリティ対策)
4. [可読性を上げる](#4.可読性を上げる)
5. [品質を上げる](#5.品質を上げる)


# 1.文法に準拠する
まずはじめに意識すべきことはIAMポリシーの文法です。
IAMポリシーには文法が定義されており、公式ドキュメントにも記載があります。
[IAM JSON ポリシー言語の文法](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_grammar.html)
ポリシーの各要素で記述ルールが決まっており、一貫性が保たれ誰でも理解しやすく問題発生時に原因を特定しやすい構造になっています。

| 要素 | 概要 |
| --- | --- |
| Version | ポリシーのバージョンを指定、通常は"2012-10-17" |
| Statement | ポリシーの主要要素、ポリシーは1つ以上のステートメントを含む |
| Effect | アクションを許可(Allow) or 拒否(Deny)するかを指定 |
| Action | 許可 or 拒否するアクションを指定 <br> 例)　```"Action": "s3:GetObject"``` |
| Resource | アクションが適用されるリソースを指定 <br> 例)　```"Resource": "arn:aws:s3:::example-bucket/*"``` |
| Condition | 特定の条件下でのみアクセスを許可or拒否するための条件を指定 <br> アクセス制御をより細かく指定可能 <br> 例)　```“Condition": { "IpAddress": { "aws:SourceIp": "11.22.33.0/24" } }``` |

ポリシーの作成や更新時で文法に準拠していない場合はエラーになるため、現時点では文法エラーがあるポリシーは作成できない仕様になっています。
まずは「公式ドキュメントを読んで文法をしっかり理解する」ことから始めましょう。

# 2.機能を満たす
文法が正しくても、作成したポリシーが期待通りに機能しなければ意味がありません。
以下のポリシーの各要素で定義した内容に対して、正しい効果が適用されているのかを検証したいです。
- 効果(Effect)：指定した効果が適用されるか
- アクション(Action)：指定したアクションに対する効果があるか
- リソース(Resource)：指定したリソースに対する効果があるか
- 条件(Condition)：キーや演算子、適用範囲が正しく適用されるか

検証方法として、作成したポリシーをユーザー/リソースに割り当てて動作確認する方法がありますが、意図しないアクセス許可を付与してしまったり、コストの発生を招いてしまうリスクがあります。
そのため、実際のユーザー/リソースに影響のない範囲で、IAMポリシーを検証することが望ましいです。
そういった時に役立つサービスとして**IAMポリシーシミュレーター**があります。

### IAMポリシーシミュレーター
ポリシーをテストおよびデバッグするためのサービスで、ポリシーが意図したとおりに機能しているかどうかを確認できます。
具体的にはポリシーに対して
- 特定アクションに対するアクセス許可/拒否の設定があるか
- 設定された条件が正しく機能しているか

などの観点でテストを実行できます。テストの結果、ポリシーが期待通りに動作しない場合はシミュレーターにて問題箇所をガイダンスしてくれるため、エラーの原因特定や修正に便利です。
ポイントとして、あくまでシミュレーションを目的とした機能のため**AWSリソースとは切り分けられており、実際のリソースには影響を与えません。**

| 機能 | 概要 |
| --- | --- |
| アイデンティティポリシーのテスト | IAMユーザー、グループ、ロールに紐づくポリシーの効果をテスト <br> ・特定アクション、リソースに対するアクセス許可/拒否があるか <br> ・設定された条件(Condition)が正しく機能しているか |
| アクセス許可の境界のテスト | アクセス許可の境界（IAM Permissions boundary）で定義されたポリシーの効果をテスト |
| リソースべースポリシーのテスト | S3、SQS、SNSなどのリソースにアタッチされているリソースベースポリシーの効果をテスト |
| サービスコントロールポリシーのテスト | Organizationsに所属している場合、アイデンティティベースのポリシーに対するサービスコントロールポリシーの効果をテスト |
| 新規作成ポリシーのテスト | 新規作成するアイデンティティポリシーのテスト |

#### 使用例
- アクションレベルでアクセス可否をチェック
    - 左側のPolicy Sandboxで定義されたポリシーのシミュレート結果を右側のPolicy Simulator に表示
    - ``ec2:StopInstances``のみ``denied``と検証されたことが確認できる
![ポリシーシミュレーター.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321772/ac46d33c-877c-615f-82fc-fc725c79c762.png)

- 構文エラーがあれば問題箇所を特定し、修正のためのガイダンスを提供
    - 7行目に構文エラーが検知されたことが確認できる
![ポリシーシミュレーター2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321772/50c4dab1-9adf-8cb0-4af2-3c05a5d8bbf0.png)


# 3.セキュリティ対策
IAMポリシー作成時において一番気になることが、セキュリティかと思います。
セキュリティリスクとして
- ポリシーに過剰な権限が付与されていないか
- ポリシーによって誰がどのリソースにアクセスできるようになるか
- 意図しない外部からのアクセスを許可していないか
- セキュリティ観点で改善点や推奨事項は無いか

などがあげられますが、全てを確認するのは大変な作業です。
そういった時に役立つサービスとして**IAM Access Analyzer**があります。

### IAM Access Analyzer
AWSリソースへのアクセス権限を検証し、潜在的なセキュリティリスクを検出するサービスです。機能の一つとして、カスタムポリシーをセキュリティ基準に準じて検証する機能があります。

| 機能 | 概要 |
| --- | --- |
| 外部アクセスの検出 | 外部エンティティと共有されている組織およびアカウントのリソースを特定する |
| 未使用アクセスの検出 | 組織およびアカウント内の使用されていないアクセス権限（IAMユーザー、ロール等）を特定する |
| ポリシーの検証 | ポリシーの文法やベストプラクティスに照らして検証する |
| カスタムポリシーチェック | 指定したセキュリティ基準に照らして IAMポリシーを検証する <br> ・CheckNoNewAccess：新旧ポリシーを比較して新しいアクセスが無いか <br> ・CheckAccessNotGranted：特定の権限が含まれていないか <br> ・CheckNoPublicAccess：パブリックアクセスが許可されていないか |
| IAMポリシーの生成| CloudTrailログのアクセスアクティビティ（IAMユーザー、ロールの過去の操作実績）に基づいたIAMポリシーを生成する |

#### 使用例
許可するCIDRの範囲を拡張する変更を加えると、新しいアクセスが追加された旨を警告する例を紹介します。

- 変更前：``aws:SouceIp``を``100.100.100.100/32``に設定
![policy_before.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321772/6043f79c-6350-12ee-b134-c1e6c0ca0d1c.png)

- 変更後：``aws:SouceIp``を``100.100.100.0/24``に拡張
![policy_after.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321772/8e5dc93f-4586-e565-67ec-ed6cb9010bdf.png)

- チェック結果：「新しいアクセスが見つかりました」と表示される
![policy_after2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2321772/b19e9238-33d2-ea44-deb8-0f95f3bd8438.png)


# 4.可読性を上げる
IAMポリシーの管理で課題になる点として、ポリシーの記述だけでは「ポリシーが何を目的/意図して作成したものなのか」すぐに読み取れないことがあります。
特に条件(Condition)要素を細かく設定するケースでは、可読性が下がってしまいがちです。

対処方法として、ポリシーの目的/背景を説明などで補足する方法があります。
IAMポリシーはJSON形式でありポリシー内にコメントを記載できないため、**IAMポリシーのDescription(説明)、ステートメントのSid**を活用するとよいでしょう。

### Description
IAMポリシーの説明欄で、1つのポリシーに対して1つの説明が記述可能です。
注意点として、ポリシー作成後の説明の変更・削除は不可となります。
ポイントとして、説明欄が長いと読むことも大変になるため、ポリシーの中でも解読が難しい箇所に絞って補足を記載しておくとよいでしょう。
※参考：[CreatePolicy](https://docs.aws.amazon.com/IAM/latest/APIReference/API_CreatePolicy.html)

### Sid
IAMポリシーの要素の一つで、ステートメント毎に付与するID部です。Sidは変更可能かつステートメント毎に付与できるため、比較的自由に利用できます。
命名規則を定義して、Sidを見ただけで何を目的としたポリシーなのかある程度の判断ができるとよいです。
※参考：[IAM JSON ポリシー要素Sid](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference_policies_elements_sid.html)


# 5.品質を上げる
今までのセクションで紹介した文法、機能性、セキュリティのチェックはIAMポリシーシミュレーターやIAM Access Analyzerである程度のチェックが可能です。
しかし、以下のような、サービスだけではチェックしきれない観点があるかと思います。

- 最小権限化
    - IAMのベストプラクティスに準じた評価（一部の観点はサービスでチェック可能ですが、厳密にはチェックしきれない部分があります）
- 役割毎の要件
    - 特定のIAMユーザーやAWSサービスにどのような役割があり、その役割に基づく権限への評価
- 業務的な要件
    - 業務プロセスや業務ニーズに基づく役割への評価
- コンプライアンス要件
    - 特定の業界や組織のルール、コンプライアンス要件への評価

上記のような観点については、必ず人によるレビュー工程を設けることで、品質向上を図りましょう。

# おわりに
実際の開発現場でIAMポリシーの作成する時は、開発者のスキル面やスケジュール等の影響で、しっかりと精査しないままポリシーが乱立してしまいがちです。
今回紹介したポリシーのチェックは地味で愚直な作業ではありますが、このような作業の積み重ねによって将来のメンテナンスや拡張もスムーズに行えると思います。
今後も「ポリシーは綺麗につくる」という意識をもっていきましょう！

明日は@naoki62さんの記事です。お楽しみに！