Help us understand the problem. What is going on with this article?

バケットポリシーを使ったS3 Bucketへのアクセス制御について

More than 3 years have passed since last update.

はじめに

 S3 Bucketへのアクセスを制御したい場合、IAMポリシー、ACLまたはパケットポリシーで制御することができます。
 やり方は色々あると思いますが、今回はバケットポリシーを使ったS3 Bucketへのアクセス制御について下記3点の方法を簡単に説明して、

  1. Principalを使ったアクセス制御
  2. NotPrincipalを使ったアクセス制御
  3. Conditionを使ったアクセス制御

 Conditionを使ったS3 Bucketへのアクセス制御をおすすめします。

パケットポリシーでのアクセス制御について

Principalを使ったアクセス制御

サンプルパケットポリシー

{
    "Version": "2012-10-17",
    "Id": "Policy146935390****",
    "Statement": [
        {
            "Sid": "Stmt146935390****",
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::2847****1948:user/test-user1"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::jobbin-key"
        }
    ]
}
  • IAMユーザtest-user1の場合、バケットjobbin-keyに対するListBucket明示的にDenyされる
  • IAM User以外、IAM RoleやAWSアカウントなども指定できます。ただしIAM Groupを指定することができません。詳細はAWSのPrincipalを確認ください。

サンプルバケットポリシーの適用による結果

  • IAMユーザtest-user1の場合
    1.pic.jpg

  • test-user1以外のIAMユーザの場合
    2.pic.jpg

Principalを使ったアクセス制御の欠点

 IAM UserやIAM Roleなどを追加するたびに、バケットポリシーを更新しないといけません。(嫌な作業ですよね)

NotPrincipalを使ったアクセス制御

 NotPrincipalを使えば、指定するもの(IAM User/Role、AWS Serviceなど)のみ許可することができなすので、Principalを使ったアクセス制御の欠点を回避できます。

サンプルパケットポリシー

{
    "Version": "2012-10-17",
    "Id": "Policy146935390****",
    "Statement": [
        {
            "Sid": "Stmt146935390****",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": "arn:aws:iam::2847****1948:user/test-user1"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::jobbin-key"
        }
    ]
}
  • IAMユーザtest-user1以外の場合、バケットjobbin-keyに対するListBucket明示的にDenyされる
  • 構文などはPrincipalと同じです。詳細はAWSのNotPrincipalを確認ください。

    サンプルバケットポリシーの適用による結果

  • IAMユーザtest-user1の場合
    4.pic.jpg

  • test-user1以外のIAMユーザの場合
    3.pic.jpg

NotPrincipalを使った制御の欠点

 NotPrincipal / PrincipalはIAM Roleを指定することができます。
 IAM Roleには普通のRoleAssumeRole用のRoleといった2種類のRoleがあります。
 普通のRoleのNotPrincipalの値は
 { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }
 に対して、
 AssumeRole用のRoleのNotPrincipalの値は
 { "AWS": "arn:aws:sts::AWS-account-ID:assumed-role/role-name/role-session-name" }
 になっています。
 role-session-nameはAssumeRoleする側で指定可能ですので、変わる可能性があります。しかし、プリンシパルを指定する際に、アスタリスク( * )は ARN の一部に一致させることはできません
 下記の内容は、AWSのPricipalの説明から引用したものです。

Note
アスタリスクは、すべてのユーザー/匿名ユーザーのプレースホルダーとしてのみ使用できます。これをワイルドカードとして使用して、名前または ARN の一部に一致させることはできません。

 role-session-nameが決まっている場合は問題がありませんが、決まっていない場合はrole-session-nameごとにユーザを指定する必要があります。これはNotPrincipalを使った制御の欠点です。

 ワイルドカード( * )を使わずに,下記のサンプルバケットポリシーを使って検証してみます。

  • 別アカウントIAMユーザがロールtest-assumeroleにAssumeRoleして、バケットjobbin-keyにアクセスしてみます。
  • AssumeRole用のRoleに必要な権限を付与しています。
{
    "Version": "2012-10-17",
    "Id": "Policy146935390****",
    "Statement": [
        {
            "Sid": "Stmt146935390****",
            "Effect": "Deny",
            "NotPrincipal": {
                "AWS": "arn:aws:iam::2847****1948:role/test-assumerole"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::jobbin-key"
        }
    ]
}

サンプルバケットポリシーが問題なく適用されますが、role-session-nameを指定していないので、結果はこうなります。
8.pic.jpg

Conditionを使ったアクセス制御

Conditionを使えば、NotPrincipalを使った制御の欠点を回避できます。

具体的には、文字列条件演算子StringNotLikeとキーaws:useridを使います。
(条件演算子ArnNotLikeとキーaws:SourceArnを使ってみましたが、うまくできませんでした。別のいい方法があれば、是非教えて下さい。)

サンプルパケットポリシー

{
    "Version": "2012-10-17",
    "Id": "Policy146927794****",
    "Statement": [
        {
            "Sid": "Stmt146927793****",
            "Effect": "Deny",
            "Principal": "*",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::jobbin-key",
            "Condition": {
                "StringNotLike": {
                    "aws:userid": "AROAISXGEH----G266U2S:*"
                }
            }
        }
    ]
}
  • AssumeRole用のロールtest-assumerole以外の場合、バケットjobbin-keyに対するListBucketDenyされます。
  • test-roleのRoleId(AROAISXGEH----G266U2S)はaws iam get-roleで取得可能です。
$ aws iam get-role --role-name test-assumerole
{
    "Role": {
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Effect": "Allow",
                    "Principal": {
                        "AWS": "arn:aws:iam::8918****5875:root"
                    }
                }
            ]
        },
        "RoleId": "AROAISXGEH----G266U2S",
        "CreateDate": "2016-07-24T11:31:00Z",
        "RoleName": "test-assumerole",
        "Path": "/",
        "Arn": "arn:aws:iam::2847****1948:role/test-assumerole"
    }
}

サンプルバケットポリシーの適用による結果

  • test-assumeroleをAssumeRoleした場合
    6.pic.jpg

  • test-assumerole以外の場合
    7.pic.jpg

まとめ

 Principalを使ったアクセス制御の欠点はNotPrincipalを使えば回避できます。
 さらに、NotPrincipalを使ったアクセス制御の欠点はConditionを使えば回避できます。
 状況によって、使い分けが必要だと思いますが、S3 BucketへのアクセスをAssumeRole用のロールに限定したい場合は、Conditionの利用をおすすめします。
 以上となりますが、少しでも皆さんにお役に立てれば、嬉しいです。

jobbin
Cloud利用歴: AWS(2014~)->Alibaba Cloud(2018~)->Tencent Cloud(2019~) 日々、自分との戦い !
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした