IAMポリシーの基本的な構造(Effect、Action、Resource)を理解した次のステップとして、Conditionブロックを活用した高度なアクセス制御を学びましょう。本記事では、条件キーの種類と演算子、IPアドレス制限、MFA必須化、時間ベースの制御、そしてタグベースのアクセス制御(ABAC)まで、実践的なポリシー設計のテクニックを解説します。

Conditionブロックとは

Conditionブロックは、IAMポリシーにおいてリクエストが特定の条件を満たす場合にのみ、ステートメントの効果(Allow/Deny)を適用するための仕組みです。条件を使うことで、「特定のIPアドレスからのみアクセスを許可する」「MFA認証済みの場合のみ操作を許可する」といった細かな制御が可能になります。

Conditionブロックの基本構文

Conditionブロックは、条件演算子、条件キー、条件値の3つの要素で構成されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::example-bucket/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "192.0.2.0/24"
                }
            }
        }
    ]
}

この例では、条件演算子がIpAddress、条件キーがaws:SourceIp、条件値が192.0.2.0/24となっています。リクエスト元のIPアドレスが指定されたCIDR範囲内にある場合のみ、S3オブジェクトの取得が許可されます。

条件の評価ロジック

複数の条件を指定した場合、評価は以下のルールに従います。

flowchart TD
    A[リクエスト受信] --> B{同じ条件キーに<br/>複数の値がある?}
    B -->|Yes| C[OR評価<br/>いずれかに一致すれば真]
    B -->|No| D{複数の条件キーが<br/>ある?}
    C --> D
    D -->|Yes| E[AND評価<br/>すべての条件を満たす必要あり]
    D -->|No| F[条件評価完了]
    E --> F
条件の種類 評価ロジック
同一条件キーに複数の値 OR(いずれかに一致すれば真)
複数の異なる条件キー AND(すべてを満たす必要あり)
複数の条件演算子 AND(すべてを満たす必要あり)

条件演算子の種類

条件演算子は、リクエストコンテキストの値とポリシーで指定した値を比較する方法を定義します。用途に応じて適切な演算子を選択することが重要です。

文字列演算子

文字列の比較に使用する演算子です。

演算子 説明
StringEquals 完全一致(大文字小文字を区別)
StringNotEquals 不一致
StringEqualsIgnoreCase 完全一致(大文字小文字を区別しない)
StringLike ワイルドカード(*?)を使用した一致
StringNotLike ワイルドカードを使用した不一致

文字列演算子を使用した例を示します。

1
2
3
4
5
6
7
{
    "Condition": {
        "StringEquals": {
            "aws:PrincipalTag/Department": "Engineering"
        }
    }
}

数値演算子

数値の比較に使用する演算子です。

演算子 説明
NumericEquals 等しい
NumericNotEquals 等しくない
NumericLessThan 未満
NumericLessThanEquals 以下
NumericGreaterThan より大きい
NumericGreaterThanEquals 以上

日付演算子

日付と時刻の比較に使用する演算子です。ISO 8601形式の日付文字列またはUnixエポック時間を使用できます。

演算子 説明
DateEquals 指定日時と等しい
DateNotEquals 指定日時と等しくない
DateLessThan 指定日時より前
DateGreaterThan 指定日時より後

ブール演算子

真偽値の比較に使用する演算子です。

1
2
3
4
5
6
7
{
    "Condition": {
        "Bool": {
            "aws:SecureTransport": "true"
        }
    }
}

IPアドレス演算子

IPアドレスの比較に使用する演算子です。IPv4とIPv6の両方に対応しています。

演算子 説明
IpAddress 指定されたIPアドレス範囲内
NotIpAddress 指定されたIPアドレス範囲外

ARN演算子

Amazon Resource Name(ARN)の比較に使用する演算子です。

演算子 説明
ArnEquals ARNが完全一致
ArnLike ワイルドカードを使用したARN一致
ArnNotEquals ARNが一致しない
ArnNotLike ワイルドカードを使用したARN不一致

IfExistsサフィックス

演算子にIfExistsを付加すると、条件キーがリクエストコンテキストに存在しない場合でも条件を真として評価します。キーが存在する場合は通常の評価が行われます。

1
2
3
4
5
6
7
{
    "Condition": {
        "StringEqualsIfExists": {
            "aws:PrincipalTag/Project": "Alpha"
        }
    }
}

この例では、aws:PrincipalTag/Projectキーが存在しない場合は条件を満たしたとみなし、存在する場合は値が「Alpha」かどうかを評価します。

主要なグローバル条件キー

AWSはすべてのサービスで使用できるグローバル条件キーを提供しています。これらのキーはaws:プレフィックスで始まります。

プリンシパルに関する条件キー

リクエストを行うプリンシパル(ユーザーまたはロール)の属性を検証するための条件キーです。

条件キー 説明 値の型
aws:PrincipalArn プリンシパルのARN ARN
aws:PrincipalAccount プリンシパルが属するアカウントID 文字列
aws:PrincipalOrgID プリンシパルが属する組織ID 文字列
aws:PrincipalTag/tag-key プリンシパルにアタッチされたタグ 文字列
aws:PrincipalType プリンシパルの種類(User、Role等) 文字列

ネットワークに関する条件キー

リクエスト元のネットワーク情報を検証するための条件キーです。

条件キー 説明 値の型
aws:SourceIp リクエスト元のIPアドレス IPアドレス
aws:SourceVpc リクエストが通過したVPCのID 文字列
aws:SourceVpce リクエストが通過したVPCエンドポイントのID 文字列
aws:VpcSourceIp VPCエンドポイント経由の場合のソースIP IPアドレス

リソースに関する条件キー

操作対象のリソースの属性を検証するための条件キーです。

条件キー 説明 値の型
aws:ResourceAccount リソースを所有するアカウントID 文字列
aws:ResourceOrgID リソースが属する組織ID 文字列
aws:ResourceTag/tag-key リソースにアタッチされたタグ 文字列

リクエストに関する条件キー

リクエスト自体の属性を検証するための条件キーです。

条件キー 説明 値の型
aws:CurrentTime 現在の日時 日付
aws:SecureTransport HTTPSを使用しているか ブール
aws:RequestedRegion リクエスト先のリージョン 文字列
aws:RequestTag/tag-key リクエストで指定されたタグ 文字列
aws:TagKeys リクエストに含まれるタグキーのリスト 文字列リスト

認証に関する条件キー

MFA認証やセッションに関する条件キーです。

条件キー 説明 値の型
aws:MultiFactorAuthPresent MFA認証が行われたか ブール
aws:MultiFactorAuthAge MFA認証からの経過秒数 数値
aws:TokenIssueTime 一時認証情報の発行時刻 日付

実践的な条件キーの活用パターン

ここからは、条件キーを使った実践的なアクセス制御パターンを解説します。

IPアドレスによるアクセス制限

特定のIPアドレス範囲からのみアクセスを許可するポリシーです。社内ネットワークからのみのアクセスに制限する場合などに使用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "NotIpAddress": {
                    "aws:SourceIp": [
                        "203.0.113.0/24",
                        "198.51.100.0/24"
                    ]
                },
                "Bool": {
                    "aws:ViaAWSService": "false"
                }
            }
        }
    ]
}

このポリシーでは、指定されたIPアドレス範囲外からのリクエストを拒否します。aws:ViaAWSService条件を追加することで、AWSサービスがユーザーに代わって行うリクエスト(Forward Access Sessions)は許可されます。

MFA必須化

重要な操作にMFA認証を必須とするポリシーです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowWithMFA",
            "Effect": "Allow",
            "Action": [
                "ec2:StopInstances",
                "ec2:TerminateInstances",
                "rds:DeleteDBInstance"
            ],
            "Resource": "*",
            "Condition": {
                "BoolIfExists": {
                    "aws:MultiFactorAuthPresent": "true"
                }
            }
        }
    ]
}

BoolIfExistsを使用することで、MFA認証を使用した一時認証情報による操作と、MFAの概念がないCLI/SDKからの長期認証情報による操作の両方を適切に制御できます。

時間ベースのアクセス制御

特定の時間帯のみアクセスを許可するポリシーです。業務時間外のアクセスを制限する場合などに使用します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:*",
            "Resource": "*",
            "Condition": {
                "DateGreaterThan": {
                    "aws:CurrentTime": "2026-01-01T09:00:00+09:00"
                },
                "DateLessThan": {
                    "aws:CurrentTime": "2026-12-31T18:00:00+09:00"
                }
            }
        }
    ]
}

リージョン制限

特定のリージョンでのみ操作を許可するポリシーです。データの地理的制約がある場合やコスト管理に有効です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestedRegion": [
                        "ap-northeast-1",
                        "ap-northeast-3"
                    ]
                }
            }
        }
    ]
}

HTTPS必須化

暗号化された通信のみを許可するポリシーです。S3バケットポリシーでよく使用されます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Deny",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::secure-bucket",
                "arn:aws:s3:::secure-bucket/*"
            ],
            "Principal": "*",
            "Condition": {
                "Bool": {
                    "aws:SecureTransport": "false"
                }
            }
        }
    ]
}

ABAC(Attribute-Based Access Control)とは

ABAC(属性ベースのアクセス制御)は、タグを使用してアクセス権限を動的に制御する手法です。従来のRBAC(ロールベースのアクセス制御)と比較して、より柔軟でスケーラブルなアクセス管理を実現できます。

RBACとABACの比較

flowchart LR
    subgraph RBAC["RBAC(ロールベース)"]
        U1[ユーザーA] --> R1[開発者ロール]
        U2[ユーザーB] --> R1
        R1 --> P1[開発環境への<br/>アクセスポリシー]
        
        U3[ユーザーC] --> R2[運用者ロール]
        R2 --> P2[本番環境への<br/>アクセスポリシー]
    end
    
    subgraph ABAC["ABAC(属性ベース)"]
        U4[ユーザーA<br/>Team:Dev] --> POLICY[汎用ポリシー<br/>PrincipalTagと<br/>ResourceTagが<br/>一致すれば許可]
        U5[ユーザーB<br/>Team:Ops] --> POLICY
        
        RES1[リソース<br/>Team:Dev] --> POLICY
        RES2[リソース<br/>Team:Ops] --> POLICY
    end
比較項目 RBAC ABAC
権限の付与方法 ロール/グループへの所属 タグ(属性)の一致
ポリシー数 リソースやチームごとに個別に必要 少数の汎用ポリシーで対応可能
スケーラビリティ チーム/リソース増加時にポリシー追加が必要 タグを付与するだけで自動的に適用
管理の複雑さ ロールとポリシーの紐付け管理 タグの標準化と一貫性の維持

ABACのメリット

ABACを採用することで、以下のメリットが得られます。

ポリシー数の削減

従来のRBACでは、プロジェクトやチームごとに個別のポリシーを作成する必要がありました。ABACでは、タグの一致を条件とした汎用的なポリシーを数個用意するだけで、多くのアクセスパターンに対応できます。

新規リソースへの自動適用

新しいリソースを作成する際に適切なタグを付与すれば、既存のポリシーが自動的に適用されます。ポリシーの更新や新規作成は不要です。

チーム変更時の柔軟性

ユーザーの所属チームが変わった場合、ユーザーのタグを更新するだけでアクセス権限が自動的に切り替わります。

ABACの実装

ABACを実装するには、プリンシパル(IAMユーザー/ロール)とリソースの両方に適切なタグを付与し、条件キーを使用してタグの一致を検証するポリシーを作成します。

タグ設計のベストプラクティス

ABACを効果的に機能させるには、一貫性のあるタグ戦略が重要です。

タグキー 用途 値の例
Project プロジェクト識別 Alpha, Beta, Gamma
Team チーム識別 Engineering, Sales, Support
Environment 環境識別 Development, Staging, Production
CostCenter コストセンター CC-001, CC-002

タグの命名規則を統一し、タグポリシーを使用して組織全体で一貫性を保つことが重要です。

ABACポリシーの実装例

以下は、同じプロジェクトタグを持つリソースへのアクセスを許可するABACポリシーの例です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessToSameProjectResources",
            "Effect": "Allow",
            "Action": [
                "ec2:StartInstances",
                "ec2:StopInstances",
                "ec2:RebootInstances"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Project": "${aws:PrincipalTag/Project}"
                }
            }
        }
    ]
}

このポリシーでは、${aws:PrincipalTag/Project}というポリシー変数を使用しています。リクエスト時にプリンシパルのProjectタグの値が自動的に展開され、リソースのProjectタグと比較されます。

複数条件を組み合わせたABACポリシー

プロジェクトとチームの両方が一致する場合のみアクセスを許可するポリシーです。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessWithMatchingTags",
            "Effect": "Allow",
            "Action": [
                "ec2:*"
            ],
            "Resource": "*",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/Project": "${aws:PrincipalTag/Project}",
                    "aws:ResourceTag/Team": "${aws:PrincipalTag/Team}"
                }
            }
        }
    ]
}

リソース作成時のタグ強制

ABACを効果的に運用するには、リソース作成時に適切なタグが付与されることを保証する必要があります。以下のポリシーは、ProjectタグとTeamタグが付与されていないEC2インスタンスの起動を拒否します。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "RequireTagsOnCreation",
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": "arn:aws:ec2:*:*:instance/*",
            "Condition": {
                "StringEquals": {
                    "aws:RequestTag/Project": "${aws:PrincipalTag/Project}",
                    "aws:RequestTag/Team": "${aws:PrincipalTag/Team}"
                },
                "ForAllValues:StringEquals": {
                    "aws:TagKeys": ["Project", "Team", "Name"]
                }
            }
        },
        {
            "Sid": "AllowRunInstancesWithoutTags",
            "Effect": "Allow",
            "Action": "ec2:RunInstances",
            "Resource": [
                "arn:aws:ec2:*:*:volume/*",
                "arn:aws:ec2:*:*:network-interface/*",
                "arn:aws:ec2:*:*:security-group/*",
                "arn:aws:ec2:*:*:subnet/*",
                "arn:aws:ec2:*::image/*"
            ]
        }
    ]
}

タグの変更を防止するポリシー

ABACを破綻させないため、ユーザーが自身のタグを変更できないようにすることも重要です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "DenyTagModification",
            "Effect": "Deny",
            "Action": [
                "ec2:CreateTags",
                "ec2:DeleteTags"
            ],
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "aws:ResourceTag/Project": "${aws:PrincipalTag/Project}"
                }
            }
        }
    ]
}

S3バケットでのABAC実装例

S3バケットへのアクセス制御にABACを適用する実践例を示します。

バケットポリシーでのABAC

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowAccessToProjectFolder",
            "Effect": "Allow",
            "Principal": "*",
            "Action": [
                "s3:GetObject",
                "s3:PutObject",
                "s3:DeleteObject"
            ],
            "Resource": "arn:aws:s3:::shared-bucket/${aws:PrincipalTag/Project}/*",
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalOrgID": "o-exampleorg"
                }
            }
        }
    ]
}

このポリシーでは、プリンシパルのProjectタグの値に対応するプレフィックス(フォルダ)へのアクセスのみを許可しています。例えば、Project: Alphaタグを持つユーザーはshared-bucket/Alpha/配下のオブジェクトにのみアクセスできます。

マルチバリュー条件キーの扱い

一部の条件キー(aws:TagKeysaws:PrincipalOrgPathsなど)は複数の値を持つことがあります。これらを適切に評価するには、セット演算子を使用します。

セット演算子

演算子 説明
ForAllValues リクエストの全ての値がポリシーの値セットに含まれる
ForAnyValue リクエストの値のいずれかがポリシーの値セットに含まれる
1
2
3
4
5
6
7
{
    "Condition": {
        "ForAllValues:StringEquals": {
            "aws:TagKeys": ["Project", "Team", "Environment"]
        }
    }
}

この条件は、リクエストに含まれるすべてのタグキーが指定されたリスト(Project、Team、Environment)に含まれている場合に真となります。許可されていないタグキーが含まれている場合は偽となります。

条件キーの可用性に関する注意点

条件キーは、すべてのリクエストコンテキストで利用できるわけではありません。例えば、aws:SourceIpはVPCエンドポイント経由のリクエストでは利用できません。条件キーが存在しない場合の動作を理解し、IfExistsサフィックスを適切に使用することが重要です。

flowchart TD
    A[条件キーの評価] --> B{条件キーが<br/>リクエストに<br/>存在する?}
    B -->|Yes| C[通常の条件評価]
    B -->|No| D{IfExistsを<br/>使用している?}
    D -->|Yes| E[条件を真として評価]
    D -->|No| F[条件を偽として評価<br/>ポリシーが適用されない]

まとめ

IAMポリシーの条件キーとABACを活用することで、きめ細かなアクセス制御を実現できます。

条件キーを使用する際のポイントをまとめます。

  • Conditionブロックで条件演算子、条件キー、条件値を組み合わせて使用する
  • 複数の条件は暗黙的にAND評価される
  • IfExistsサフィックスを使用して、条件キーが存在しない場合の動作を制御する
  • IPアドレス制限、MFA必須化、リージョン制限など、用途に応じた条件を設計する

ABACを導入する際のポイントをまとめます。

  • タグの命名規則を統一し、組織全体で一貫性を保つ
  • aws:PrincipalTagaws:ResourceTagを組み合わせて動的なアクセス制御を実現する
  • リソース作成時のタグ付けを強制するポリシーを設定する
  • 重要なタグの変更を防止するポリシーを設定する

条件キーとABACを適切に組み合わせることで、スケーラブルで管理しやすいアクセス制御を実現できます。次回は、IAM Access Analyzerを使用した権限の分析と最適化について解説します。

参考リンク