特定のIAMロールのみS3バケットにアクセスできるS3バケットポリシー設定


この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので十分ご注意ください。

【課題】

プロジェクトで本番環境のファイルをS3バケット経由で持ち込み・持ち出しするアーキテクチャを構築します。
S3バケットに特定のIAMロールのみ(WindowsFileServerEC2インスタンスにアタッチするRoleA、別アカウントからスイッチロールするRoleB)アクセスし、それ以外のアクセスが拒否するという要件があります。

【解決策】

バケットポリシーに「NotPrincipal」を使う、と「Condition」にaws:useridを使うという2つ方法があります。

【バケットポリシーにNotPrincipalを使用する方法】

バケットポリシー例

{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Deny",
        "NotPrincipal": {"AWS": [
            "arn:aws:sts::444455556666:assumed-role/cross-account-read-only-role/cross-account-audit-app",
            "arn:aws:iam::444455556666:role/cross-account-read-only-role",
            "arn:aws:iam::444455556666:root"
        ]},
        "Action": "s3:*",
        "Resource": [
            "arn:aws:s3:::Bucket_AccountAudit",
            "arn:aws:s3:::Bucket_AccountAudit/*"
        ]
    }]
}

制限事項

NotPrincipal 要素で引き受けたロールセッションを指定する場合、ワイルドカード (*) を使用して「すべてのセッション」を意味することはできません。プリンシパルは常に特定のセッションに名前を付ける必要があります。

別アカウントからスイッチロールする場合、スイッチ元のユーザーが特定できない。NotPrincipalにワイルドカード*が使用できませんのでこの案はNGです。

【バケットポリシーにCondition+aws:useridを使用する方法】

バケットポリシー例

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::MyExampleBucket",
        "arn:aws:s3:::MyExampleBucket/*"
      ],
      "Condition": {
        "StringNotLike": {
          "aws:userId": [
            "AROAEXAMPLEID:*",
            "111111111111"
          ]
        }
      }
    }
  ]
}

注意事項

Condition.StringNotLike ではワイルドカード * を使用できますので要求を実現できます。この案はOKです。
ただ、useridはIAMユーザーやロールに割り当てられる一意のIDです。マネジメントコンソールから確認することができません。awscli などの get-roleで取得する必要があります。
参照URL
IAM 識別子

【残課題】

バケットポリシーに拒否の条件を追加すると、「サーバーアクセスのログ記録」を有効化にしたとしてもS3 ログ配信グループがS3へ書き込みする権限がなくなるため、ログ記録のターゲットが自分自身の場合、Amazon S3 からアクセスログを配信できなくなります。
そのため、アクセスログのターゲットは別のバケットを設定しました。

参照URL
How to Restrict Amazon S3 Bucket Access to a Specific IAM Role

AWS JSON ポリシーの要素: NotPrincipal

Last modified: 2024-02-05

Author