aws:PrincipalArn 条件コンテキストキーで IAM グループのプリンシパル ARN を指定できるのか試してみた

Principal 要素で IAM グループは指定できないのに条件キー aws:PrincipalArn では指定できるの?ということが気になったので調べてみました。

コンバンハ、千葉(幸)です。

とある事情から IAM の AWS ドキュメントを上から下まで読んでいたのですが、IAM アクセスアナライザーの結果(Finding)のフィルタリングに関する記述で気になる部分を見つけました。

  • Principal ARN – Use this property to filter on the ARN of the principal (IAM user, role, or group) used in an aws:PrincipalArn condition key. To filter by Principal ARN, type all or part of the ARN of the IAM user, role, or group from an external AWS account reported in a finding.

機械翻訳結果はこちら。

  • プリンシパル ARN - aws:PrincipalArn 条件キーで使用されるプリンシパル(IAM ユーザー、ロール、またはグループ)の ARN でフィルタリングするには、このプロパティを使用します。プリンシパルARNでフィルタリングするには、発見で報告された外部AWSアカウントのIAMユーザー、ロール、またはグループのARNのすべてまたは一部を入力します。

IAM アクセスアナライザーによるリソースベースポリシーの分析により「結果(Finding)」が生成されます。その結果をフィルタリングするためにPrincipal ARNを指定できる、ということが記されています。

気になるのはプリンシパルの中にグループが含まれていることで、これはおそらく IAM グループを指しているのだと考えました。IAM ユーザーやロールはともかく、IAM グループが指定できるとすると違和感あるな……と感じたので調べてみました。

まとめ

  • aws:PrincipalArn条件コンテキストキーの値に IAM グループの ARN を指定することはできるが、Effect(Allow / Deny)は正常に機能しない
  • IAM アクセスアナライザーの結果のフィルタリングに IAM グループのプリンシパル ARN を使用すること自体はできる
    • でもそれを使う機会があるのかはちょっと分からない

今回の構成

検証を行う構成は以下のイメージです。

  • 実行元アカウント:000000000000
    • IAM ユーザー:Batchi
      • IAM グループAdministratorに所属している
      • IAM ポリシーAdministratorAccessがアタッチされている
  • 実行先アカウント:999999999999
    • S3 バケット:chibayuki-hoge-hoge

S3 バケットchibayuki-hoge-hogeのバケットポリシーを変更しながら、挙動の変化を確認します。

IAM ユーザー側では AdministratorAccess がアタッチされているため、S3 バケット側で Allow が与えられればクロスアカウントでの S3 へのアクションが成功するようになります。

ドキュメントで aws:PrincipalArn について確認する

実際に手を動かす前に、もう少しドキュメントで調べてみます。

冒頭で引用した文章では、「 aws:PrincipalArn 条件キーで使用されるプリンシパル(IAM ユーザー、ロール、またはグループ)の ARN でフィルタリングするには……」とあります。

条件キーaws:PrincipalArnについては以下から確認できます。

AWS_Identity_and_Access_Management_Global_Condition_Key

このキーを使用して、リクエストを行ったプリンシパルの Amazon リソースネーム (ARN) をポリシーで指定した ARN と比較します。IAM ロールの場合、リクエストコンテキストは、ロールを引き受けたユーザーの ARN ではなく、ロールの ARN を返します。この条件キーで指定できるプリンシパルのタイプについては、「プリンシパルの指定」を参照してください。

前後の文章から、条件演算子として ARN 演算子と文字列演算子が使用できることと、この条件キーがすべてのリクエストコンテキストに含まれることが分かりました。ここで指定できるプリンシパルのタイプについては別ドキュメントに記載されているためそちらを確認します。

Principal_-_AWS_Identity_and_Access_Management

AWS JSON ポリシーの Principal 要素で指定できるプリンシパルとして以下が記載されています。

  • AWS アカウントと ルートユーザー
  • IAM ユーザー
  • フェデレーティッドユーザー(ウェブ ID または SAML フェデレーションを使用)
  • IAM ロール
  • ロールを引き受けるセッション
  • AWS サービス
  • 匿名ユーザー(非推奨)

ここに IAM グループが記載されていないため、条件キーaws:PrincipalArnにおいてもプリンシパルとしては指定できない、という捉え方をしたくなります。

やってみた

以下のパターンを試行します。

  1. Principal 要素で IAM グループを指定する
  2. Principal 要素で IAM ユーザーを指定する
  3. 条件キー aws:PrincipalArn で IAM グループを指定する
  4. 条件キー aws:PrincipalArn で IAM ユーザーを指定する

先に結論から言うと以下の結果になります。

パターン バケットポリシー アナライザーの結果
1. Principal 要素で IAM グループ 保存できない
2. Principal 要素で IAM ユーザー 正常に機能する 外部プリンシパルとして検出される
3. aws:PrincipalArn で IAM グループ 保存できるが機能しない 条件の中のプリンシパル ARN として表示される
4. aws:PrincipalArn で IAM ユーザー 正常に機能する 条件の中のプリンシパル ARN として表示される

1. Principal 要素で IAM グループのプリンシパル ARN を指定してみる

本来の趣旨のaws:PrincipalArn条件キーの前に、Principal 要素への指定を試してみます。ドキュメントではサポートされているプリンシパルのタイプとして記載されていないため、設定できないことを想像します。

以下のバケットポリシーをペーストし、アナライザーによる外部アクセスプレビューを実行します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
             "Principal": {
                "AWS": [
                  "arn:aws:iam::000000000000:group/Administrator"
                ]
              },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::chibayuki-hoge-hoge",
                "arn:aws:s3:::chibayuki-hoge-hoge/*"
            ]
        }
    ]
}

access_preview

プレビューでは「外部プリンシパル」として IAM グループのプリンシパル ARN が表示されます。

AccessAnalyzer-group

この状態でバケットポリシーの保存を実行すると、エラーとなります。

S3BucketPolicy

プレビューでは外部プリンシパルとして記録されるものの、実際にはバケットポリシーとして保存できない無効な値であることが分かりました。

2. Principal 要素で IAM ユーザーのプリンシパル ARN を指定してみる

続いてプリンシパルタイプとしてサポートされている IAM ユーザーを指定してみます。

バケットポリシーは以下の通りです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
             "Principal": {
                "AWS": [
                  "arn:aws:iam::000000000000:user/Batchi"
                ]
              },
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::chibayuki-hoge-hoge",
                "arn:aws:s3:::chibayuki-hoge-hoge/*"
            ]
        }
    ]
}

外部アクセスのプレビューでは、先ほどと同じように外部プリンシパルとして IAM ユーザーが記録されます。

AccessAnalyzer-preview

バケットポリシーは正常に保存できます。

アクセスアナライザーでは IAM ユーザーが外部プリンシパルとして検出されています。

IAM_Management_Console_AccessAnalyzer

AWS CLI の実行

実行元の IAM ユーザーとして AWS CLI が実行できる状態です。

% aws sts get-caller-identity
{
    "UserId": "AIDARVFQHJ6WFBJFMWCB4",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/Batchi"
}

プリンシパルとして Allow が与えられているため、実行先アカウントにある S3 バケットの中身を問題なく参照できました。

% aws s3 ls chibayuki-hoge-hoge
2021-10-17 18:18:35          6 test.txt

3. 条件キー aws:PrincipalArn で IAM グループのプリンシパル ARN を指定してみる

本エントリの本題がここです。

ここまでは Principal 要素で IAM グループやユーザーを指定してきましたが、ここからは条件キーaws:PrincipalArnにプリンシパル ARN を指定してみます。バケットポリシーは以下の通りです。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::chibayuki-hoge-hoge",
                "arn:aws:s3:::chibayuki-hoge-hoge/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::000000000000:group/Administrator"
                }
            }
        }
    ]
}

こちらの外部アクセスをプレビューすると以下のようになります。

AccessAnalyzer-preview-condition

↑これまでは「外部プリンシパル」にプリンシパル ARN が記載されていましたが、今回の指定では「すべてのプリンシパル」となっています。代わりに「条件」という箇所に IAM グループのプリンシパル ARN が記載されています。

このバケットポリシーを保存します。正常に保存できました。

アナライザーの結果で、IAM グループのプリンシパル ARN を指定してフィルタリングすると当該 S3 バケットの結果が表示されます。

IAM_Management_Console_Access_Analyzer

冒頭の AWS ドキュメントはこのことを示していることが分かりました。

AWS CLI の実行

ふたたび実行元アカウントから S3 バケットにアクセスを試みます。アクセスは拒否されました。

% aws sts get-caller-identity
{
    "UserId": "AIDARVFQHJ6WFBJFMWCB4",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/Batchi"
}

% aws s3 ls chibayuki-hoge-hoge

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

この条件キーの指定の仕方では Allow が与えられていないということです。IAM ユーザーBatchiは IAM グループAdministratorに所属していますが、aws:PrincipalArn 条件キーの値として IAM グループはサポートされていないためなんの効果ももたらしません。

今回のバケットポリシーは実質的になんの意味も持たず、空であるのと同じです。外部からアクセス可能な状態にはなっていません。

4. 条件キー aws:PrincipalArn で IAM ユーザーのプリンシパル ARN を指定してみる

最後に条件キーに IAM ユーザーの ARN を指定してみます。IAM ユーザーは Principal 要素でサポートされているプリンシパルタイプであるため、条件キーが正常に機能することを期待します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::chibayuki-hoge-hoge",
                "arn:aws:s3:::chibayuki-hoge-hoge/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:PrincipalArn": "arn:aws:iam::000000000000:user/Batchi"
                }
            }
        }
    ]
}

バケットポリシー変更時に外部アクセスのプレビューを行うと、ロールを指定した時と同様に、外部プリンシパルがすべて・条件として IAM ユーザーのプリンシパル ARN が記載される状態となります。

AccessAnalyzer

バケットポリシーは正常に保存できました。アナライザーを確認するとプレビューと同様の内容で結果が表示されていました。

IAM_Management_Console_Analyzer_principalarn

AWS CLI の実行

この状態で指定した IAM ユーザーから S3 へのアクセスを試みます。正常にアクセスが行えました。

% aws sts get-caller-identity
{
    "UserId": "AIDARVFQHJ6WFBJFMWCB4",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/Batchi"
}

% aws s3 ls chibayuki-hoge-hoge
2021-10-17 18:18:35          6 test.txt

もちろん条件キーで指定している IAM ユーザー以外からのアクセスは拒否されます。

% aws sts get-caller-identity
{
    "UserId": "AIDARVFQHJ6WHQVDP4LLE",
    "Account": "000000000000",
    "Arn": "arn:aws:iam::000000000000:user/Test-User"
}

% aws s3 ls chibayuki-hoge-hoge

An error occurred (AccessDenied) when calling the ListObjectsV2 operation: Access Denied

4パターンのまとめ

冒頭で示した通り以下の結果となりました。

パターン バケットポリシー アナライザーの結果
1. Principal 要素で IAM グループ 保存できない
2. Principal 要素で IAM ユーザー 正常に機能する 外部プリンシパルとして検出される
3. aws:PrincipalArn で IAM グループ 保存できるが機能しない 条件の中のプリンシパル ARN として表示される
4. aws:PrincipalArn で IAM ユーザー 正常に機能する 条件の中のプリンシパル ARN として表示される

終わりに

aws:PrincipalArn 条件キーでプリンシパルとして IAM グループを指定できるのか?という確認でした。結果としては、「指定自体はできるが正常に機能しない(何の効果も及ぼさない)」であることが分かりました。

正直に言うと冒頭で引用した AWS ドキュメントの以下記載は誤りなのではないか(グループがここに含まれているのは誤りではないか)と考えていたのですが、そうではありませんでした。

aws:PrincipalArn 条件キーで使用されるプリンシパル(IAM ユーザー、ロール、またはグループ)の ARN でフィルタリングするには、このプロパティを使用します。

(効果は及ぼさないものの)条件キーで設定自体はできるので、アナライザーの結果のフィルタリングで IAM グループのプリンシパル ARN を指定することもできるというわけです。

理想を言えば効果を及ぼさないのであれば設定自体ができないようになっていれば嬉しいのですが、そうもいかないのだろうと想像します。改めて IAM って難しいなと思いました。(そしてそこがわたしを惹きつけて止まないのでしょう。)

以上、 チバユキ (@batchicchi) がお送りしました。