IAMロールとポリシーを使いこなすためのポイント(2/2)

この記事は、ソリューションアーキテクトの勉強を始めた方やIAMについての理解を深めたい方向けに作成しています。

## IAMポリシーとは？
IAMポリシーは、AWSリソースへのアクセスを許可または拒否するアクセス権限を設定するJSONドキュメントです。ポリシーは、IAM ユーザー、グループ、ロール、またはリソースにアタッチされ、AWS 環境内でのアクセス制御を行います。IAM ポリシーは、2つのタイプがあります。

### アイデンティティベースのポリシー
IAM ユーザー、グループ、ロールにアタッチされるポリシーで、そのエンティティが実行できるアクションを定義します。
### リソースベースのポリシー
特定の AWS リソース（例えば、S3 バケットや Lambda 関数）に直接アタッチされるポリシーで、そのリソースにアクセスできるプリンシパルを定義します。

# アイデンティティベースのポリシーとリソースベースのポリシーの比較

| 特徴 | アイデンティティベースのポリシー | リソースベースのポリシー |
|------|--------------------------------|--------------------------|
| **定義** | IAM ユーザー、グループ、ロールにアタッチされるポリシー | AWS リソース(S3バケット、SQSキュー、VPCエンドポイントなど)に直接アタッチされるポリシー |
| **アクセス許可** | ユーザーやロールが実行できるアクションとリソースを指定 | 特定のリソースに対するアクセスを許可するプリンシパルを指定 |
| **使用例** | ユーザーが実行できるサービスやアクションを制限 | S3 バケットポリシーを使用して特定のユーザーにバケットへのアクセスを許可 |
| **スコープ** | アカウント内のすべてのリソースに適用可能 | 特定のリソースにのみ適用 |
| **管理** | IAM ダッシュボードまたは AWS CLI を通じて管理 | リソース固有のコンソールまたは API を通じて管理 |
| **再利用性** | ポリシーを複数のユーザーやロールに再利用可能 | 各リソースに個別に設定する必要がある |
| **主な利点** | 一元的なアクセス管理 | リソースレベルでの細かいアクセス制御 |
| **主な制限** | リソースごとの細かい制御が困難 | リソースごとにポリシーを設定する必要がある |


### アイデンティティベースのポリシー 

IAM ユーザーに Amazon S3 バケットへの読み取りアクセスを許可しています。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        }
    ]
}
```

### リソースベースのポリシーのサンプル (S3 バケットポリシー)

特定の IAM ユーザーに対して、指定された S3 バケットへの読み取りアクセスを許可しています。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:user/ExampleUser"
            },
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        }
    ]
}
```

アイデンティティベースのポリシーは、__IAM ユーザー、グループ、またはロールにアタッチ__ され、そのエンティティが実行できるアクションを定義します。一方、リソースベースのポリシーは、__特定の AWS リソース（この場合は S3 バケット）に直接アタッチ__ され、そのリソースにアクセスできるエンティティ（IAM ユーザー、ロール、AWS アカウントなど）を定義します。リソースベースのポリシーは、クロスアカウントアクセスを許可する場合などに特に有用です。

### AWS公式サイトを確認し、__「IAM でのポリシーとアクセス許可」の要点__ を整理しました。
https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/access_policies.html

## アクセスを管理するための6つのポリシータイプ

| ポリシータイプ | 説明 | 適用対象 | 特徴 |
|----------------|------|----------|------|
| アイデンティティベースのポリシー | IAM ID (ユーザー、グループ、ロール) にアタッチする | アイデンティティ | 管理ポリシーとインラインポリシーがある |
| リソースベースのポリシー | リソースに直接アタッチされる | リソース | S3 バケットポリシーや IAM ロールの信頼ポリシーが一般的 |
| アクセス許可の境界 | IAM エンティティのアクセス許可の上限を定義 | アイデンティティ | アクセス許可は付与されない |
| Organizations SCP | 組織または組織単位のメンバーアカウントのアクセス許可の上限を定義 | 組織 | アイデンティティベースのポリシーやリソースベースのポリシーで付与するアクセス許可が制限される |
| アクセスコントロールリスト (ACL) | 他のアカウントのプリンシパルにアクセス許可を付与 | リソース | JSON ポリシードキュメント構造を使用しない |
| セッションポリシー | ロールまたはフェデレーティッドユーザーのセッションにアクセス許可を制限 | セッション | アクセス許可は付与されない |

### IAMポリシーの例
この例では、特定の S3 バケットに対する読み取りアクセスを許可するポリシーを作成しています。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::example-bucket",
                "arn:aws:s3:::example-bucket/*"
            ]
        }
    ]
}
```

- `Statement`: 許可(拒否)を複数指定します。
- `Effect`: 許可(Allow)拒否(Deny)を設定します。
- `Action`: 許可されるアクションのAPIを指定します。この例では、"s3:GetObject" と "s3:ListBucket" が許可されています。
- `Resource`: ポリシーが適用されるリソースのリストを指定します。この例では、"example-bucket" とその中のすべてのオブジェクトが対象です。

このポリシーを IAM ユーザー、グループ、またはロールに __アタッチすると__、指定された S3 バケットに対する読み取りアクセスが許可されます。ポリシーは JSON 形式で記述され、AWS Management Console、AWS CLI、または AWS SDK を通じて __IAM エンティティにアタッチ__ できます。
### AWS IAM ポリシーで接続元制限を設定する場合
`Condition` 要素を使用して特定の IP アドレス範囲からのアクセスのみを許可するようにポリシーを設定することができます。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:DescribeInstances",
            "Resource": "*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "203.0.113.0/24",
                        "198.51.100.0/24"
                    ]
                }
            }
        }
    ]
}
```

このポリシーでは、`ec2:DescribeInstances` アクションを許可していますが、`Condition` 要素により、指定された IP アドレス範囲（この例では `203.0.113.0/24` と `198.51.100.0/24`）からのリクエストのみが許可されます。

### 複雑なIAMポリシーの例
IAM ロールにアタッチされる IAM ポリシーには、`Condition` 要素を使用して、特定の条件が満たされた場合にのみポリシーが適用されるようにすることができます。`Condition` 要素とそのオペレーター（`StringEquals`、`NumericLessThanEquals`、`DateEquals`、`DateGreaterThan`、`Bool`、`ArnEquals`）を使用したサンプルポリシーを示します。

### ポリシー変数を使ったIAMポリシー

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example-bucket/*",
            "Condition": {
                "StringEquals": {
                    "s3:prefix": "home/"
                },
                "NumericLessThanEquals": {
                    "aws:MultiFactorAuthAge": "3600"
                },
                "DateGreaterThan": {
                    "aws:CurrentTime": "2023-01-01T12:00:00Z"
                },
                "Bool": {
                    "aws:MultiFactorAuthPresent": "true"
                },
                "ArnEquals": {
                    "aws:SourceArn": "arn:aws:s3:::source-bucket"
                }
            }
        }
    ]
}
```
- `StringEquals`: オブジェクトのプレフィックスが "home/" である場合にのみ `s3:GetObject` アクションを許可します。
- `NumericLessThanEquals`: マルチファクタ認証 (MFA) の年齢が 3600 秒以下の場合にのみアクションを許可します。
- `DateGreaterThan`: 現在の日時が "2023-01-01T12:00:00Z" より後の場合にのみアクションを許可します。
- `Bool`: ユーザーが MFA を使用して認証されている場合にのみアクションを許可します。
- `ArnEquals`: ソースの ARN が "arn:aws:s3:::source-bucket" と等しい場合にのみアクションを許可します。

これらの条件は、IAM ポリシーの `Condition` 要素内で組み合わせて使用され、特定のシナリオでのみアクセス許可を制限するために役立ちます。ポリシーは JSON 形式で記述され、IAM ロールにアタッチされることで、ロールを引き受けるエンティティのアクセスを制御します。

### ポリシー変数

IAM ポリシーでは、ポリシー変数を使用して、ポリシーの再利用性を高め、動的な値をポリシーに組み込むことができます。この例では、IAM ユーザーが自分の Amazon S3 ホームディレクトリ内のオブジェクトにのみアクセスできるように制限しています。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::example-bucket/home/${aws:username}/*"
        }
    ]
}
```

- `Action`: "s3:GetObject"、"s3:PutObject"、"s3:DeleteObject" は、ユーザーが S3 バケット内のオブジェクトを取得、アップロード、削除できることを示します。
- `Resource`: "arn:aws:s3:::example-bucket/home/${aws:username}/*" は、ポリシー変数 `${aws:username}` を使用して、IAM ユーザーが自分のユーザー名に対応する "home" ディレクトリ内のオブジェクトにのみアクセスできることを示します。たとえば、ユーザー名が "john" の場合、このユーザーは "example-bucket/home/john/" 内のオブジェクトにのみアクセスできます。

ポリシー変数を使用することで、同じポリシーを複数のユーザーに適用し、それぞれのユーザーが自分のリソースにのみアクセスできるようにすることができます。これにより、ポリシーの管理が簡素化され、セキュリティが向上します。

### ポリシー変数とタグ

IAM ポリシーでは、変数とタグを使用して、ポリシーをより動的かつ柔軟にすることができます。IAM ユーザーのタグに基づいて特定の S3 バケットへのアクセスを許可するサンプルポリシーを示します。

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::${aws:PrincipalTag/Department}/*"
            ],
            "Condition": {
                "StringLike": {
                    "aws:RequestTag/Department": "${aws:PrincipalTag/Department}"
                }
            }
        }
    ]
}
```

- `Action`: "s3:*" は、ユーザーが S3 バケット内のすべてのアクションを実行できることを示します。
- `Resource`: "arn:aws:s3:::${aws:PrincipalTag/Department}/*" は、IAM ユーザーに設定された "Department" タグの値に基づいて、対応する S3 バケットへのアクセスを許可します。たとえば、ユーザーの "Department" タグが "marketing" であれば、"example-bucket/marketing/*" へのアクセスが許可されます。
- `Condition`: "StringLike" と "aws:RequestTag/Department" を使用して、リクエストに含まれる "Department" タグが IAM ユーザーの "Department" タグと一致する場合にのみアクセスを許可します。

このポリシーにより、IAM ユーザーは自分の部門に対応する S3 バケットにのみアクセスでき、他の部門のバケットにはアクセスできないようになります。これにより、組織内のリソースへのアクセスを部門ごとに分離し、セキュリティを強化することができます。

### IAMロールの信頼ポリシー

IAM ロールの信頼ポリシー（Trust Policy）は、そのロールを引き受けることができるエンティティ（プリンシパル）を定義する JSON ドキュメントです。信頼ポリシーは、IAM ロールの一部として設定され、どの AWS サービスやアカウントがロールを使用できるかを指定します。これにより、ロールを引き受けることが許可されるプリンシパルが制限され、セキュリティが強化されます。

この例では、AWS Lambda サービスがロールを引き受けることを許可しています。

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

- `Principal`: ロールを引き受けることが許可されるエンティティを指定します。この例では、AWS Lambda サービスが指定されています。
- `Action`: 許可されるアクションを指定します。この例では、"sts:AssumeRole" が許可されており、これにより AWS Lambda サービスがロールを引き受けることができます。

信頼ポリシーを使用することで、IAM ロールを安全に他のサービスやアカウントと共有でき、特定のタスクやアプリケーションに必要な権限を付与することができます。

IAMロールとポリシーを使いこなすためのポイント(1/2)
https://qiita.com/kimuni-i/items/0e55a40c78c21606544e