IAM ポリシーで他人の S3 バケット・EC2 キーペアを削除できなくさせる方法

2023.02.14

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

はじめに

こんにちは、アノテーション構築チームの荒川です。

開発者へ AWS 管理ポリシーの PowerUserAccess をアタッチしている環境で、S3 バケットと EC2 キーペアは、自分のリソースだけ操作できるようにしたい、といった要望がありました。

この要望に対して AWS マネジメントコンソールで、 IAM ポリシーを追加する方法の手順を紹介します。

自分の IAM ユーザー名が入った S3 バケットだけ、変更(削除含む)可能にするポリシーの作成手順

1. IAM コンソールの ポリシーへアクセス
2. 「ポリシーを作成」ボタンをクリック
3. 「ビジュアルエディタ」タブから「JSON」タブへ変更する
4. 下記のポリシーをコピーして貼り付ける

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "S3WriteOnlyMyOwnBucketPolicy",
            "Effect": "Deny",
            "Action": [
                "s3:CreateAccessPoint",
                "s3:SubmitMultiRegionAccessPointRoutes",
                "s3:PutAnalyticsConfiguration",
                "s3:PutAccelerateConfiguration",
                "s3:PutAccessPointConfigurationForObjectLambda",
                "s3:DeleteObjectVersion",
                "s3:PutStorageLensConfiguration",
                "s3:RestoreObject",
                "s3:DeleteAccessPoint",
                "s3:CreateBucket",
                "s3:DeleteAccessPointForObjectLambda",
                "s3:ReplicateObject",
                "s3:PutEncryptionConfiguration",
                "s3:DeleteBucketWebsite",
                "s3:AbortMultipartUpload",
                "s3:PutLifecycleConfiguration",
                "s3:UpdateJobPriority",
                "s3:DeleteObject",
                "s3:CreateMultiRegionAccessPoint",
                "s3:DeleteBucket",
                "s3:PutBucketVersioning",
                "s3:PutIntelligentTieringConfiguration",
                "s3:PutMetricsConfiguration",
                "s3:PutBucketOwnershipControls",
                "s3:PutReplicationConfiguration",
                "s3:DeleteMultiRegionAccessPoint",
                "s3:PutObjectLegalHold",
                "s3:InitiateReplication",
                "s3:UpdateJobStatus",
                "s3:PutBucketCORS",
                "s3:PutInventoryConfiguration",
                "s3:PutObject",
                "s3:PutBucketNotification",
                "s3:DeleteStorageLensConfiguration",
                "s3:PutBucketWebsite",
                "s3:PutBucketRequestPayment",
                "s3:PutObjectRetention",
                "s3:PutBucketLogging",
                "s3:CreateAccessPointForObjectLambda",
                "s3:PutBucketObjectLockConfiguration",
                "s3:CreateJob",
                "s3:ReplicateDelete"
            ],
            "NotResource": [
                "arn:aws:s3:::*${aws:username}*",
                "arn:aws:s3:::*${aws:username}/*"
            ]
        }
    ]
}

5. 「次のステップ: タグ」ボタンをクリック
6. 「次のステップ: 確認」ボタンをクリック
7. 名前、説明にそれぞれ「S3WriteOnlyMyOwnBucketPolicy」を入力
8. 「ポリシーの作成」ボタンをクリック
9. 画面上部に作成が完了した旨のメッセージが出ることを確認

自分の IAM ユーザー名が入った EC2 キーペアだけ、削除可能にするポリシーの作成手順

1. IAM コンソールの ポリシーへアクセス
2. 「ポリシーを作成」ボタンをクリック
3. 「ビジュアルエディタ」タブから「JSON」タブへ変更する
4. 下記のポリシーをコピーして貼り付ける(完全一致か部分一致かいずれか選択)

以下の例は「arakawa-key-pair」のように、ユーザー名の後に「-key-pair」を固定で付ける例です。「-key-pair」の箇所は運用に合わせて変更してください。

キーペア名を完全一致で判定するパターン

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2DeleteOnlyMyOwnKeyPair",
            "Effect": "Deny",
            "Action": "ec2:DeleteKeyPair",
            "Resource": "*",
            "Condition": {
                "StringNotEquals": {
                    "ec2:KeyPairName": "${aws:username}-key-pair"
                }
            }
        }
    ]
}

キーペア名を部分一致で判定するパターン

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "EC2DeleteOnlyMyOwnKeyPair",
            "Effect": "Deny",
            "Action": "ec2:DeleteKeyPair",
            "Resource": "*",
            "Condition": {
                "StringNotLike": {
                    "ec2:KeyPairName": "*${aws:username}-key-pair*"
                }
            }
        }
    ]
}

5. 「次のステップ: タグ」ボタンをクリック
6. 「次のステップ: 確認」ボタンをクリック
7. 名前、説明にそれぞれ「EC2DeleteOnlyMyOwnKeyPair」を入力
8. 「ポリシーの作成」ボタンをクリック
9. 画面上部に作成が完了した旨のメッセージが出ることを確認

作成した IAM ポリシーを IAM ユーザーへアタッチする手順

個別の IAM ユーザーへポリシーを追加したい場合、以下の手順を実施します。まとめてポリシーを管理したい場合は、後述する IAM グループを使います。

  1. IAM コンソールの IAM ユーザーへアクセス
  2. ポリシーをアタッチしたいユーザー名をクリック
  3. 「許可を追加」->「許可を追加」をクリック
  4. 「ポリシーを直接アタッチする」をクリック
  5. 許可ポリシー検索欄に「S3WriteOnlyMyOwnBucketPolicy」を入力
  6. 表示される IAM ポリシー: S3WriteOnlyMyOwnBucketPolicy をチェック
  7. 許可ポリシー検索欄に「EC2DeleteOnlyMyOwnKeyPair」を入力
  8. 表示される IAM ポリシー: EC2DeleteOnlyMyOwnKeyPair をチェック
  9. 「次へ」をクリック
  10. 「許可を追加」をクリック
  11. 画面上部にポリシーが追加された旨のメッセージが出ることを確認

作成した IAM ポリシーを既存の IAM グループへアタッチする手順

IAM ユーザーがすでに IAM グループへ所属している場合は、そのグループへ作成したポリシーを追加します。

  1. IAM コンソールの ユーザーとグループへアクセス
  2. グループ名の一覧から対象のグループ名をクリック(グループがない場合は先にグループを作成する)
  3. 「ユーザー」タブから「許可」タブへ変更する
  4. 「許可を追加」->「ポリシーをアタッチ」をクリック
  5. その他の許可ポリシー検索欄に「S3WriteOnlyMyOwnBucketPolicy」を入力
  6. 表示される IAM ポリシー: S3WriteOnlyMyOwnBucketPolicy をチェック
  7. 「フィルターをクリア」ボタンをクリック
  8. その他の許可ポリシー検索欄に「EC2DeleteOnlyMyOwnKeyPair」を入力
  9. 表示される IAM ポリシー: EC2DeleteOnlyMyOwnKeyPair をチェック
  10. 「許可を追加」をクリック
  11. 画面上部にポリシーが追加された旨のメッセージが出ることを確認

おわりに

ポイントとしては、S3 のバケットは ARN でリソースを指定したポリシーを作れますが、EC2 のキーペアはリソースの指定ができず * のみになることです。
S3 は NotResource 句で、キーペアは Condition 句を使って制御してみました。

Condition 句で制御する際、部分一致(*/?)を使いたい場合は StringNotEquals ではなく、StringNotLike にするよう気をつけてください。
StringNotEquals で部分一致を使うと、ポリシーの作成はできますが、自分の名前が入ったアクセスキーでも削除できなくなります。

参考

アノテーション株式会社について

アノテーション株式会社は、クラスメソッド社のグループ企業として「オペレーション・エクセレンス」を担える企業を目指してチャレンジを続けています。「らしく働く、らしく生きる」のスローガンを掲げ、さまざまな背景をもつ多様なメンバーが自由度の高い働き方を通してお客様へサービスを提供し続けてきました。現在当社では一緒に会社を盛り上げていただけるメンバーを募集中です。少しでもご興味あれば、アノテーション株式会社WEBサイトをご覧ください。