[アップデート] IAM アクセスアドバイザーによる「アクションレベルでの最終実行履歴の表示」に EC2、IAM、Lambda が対応しました!

過去に呼び出していないアクションは不要だから権限を絞りたい、という場合にとてもお手軽です

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

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

IAM アクセスアドバイザーで、新たに EC2、IAM、Lambda もアクションレベルで最終アクセス時刻を確認できるようになりました!

必要最小限の権限に絞っていく、そのアプローチがまた一つ楽になりました。

何が変わったのか

IAM アクセスアドバイザーは、特定の IAM リソース(ユーザー/グループ/ロール/ポリシー)に対して以下を分析、取得してくれる機能です。

  • アクセス可能な AWS サービス
  • 最終アクセス時刻

IAM リソースのアイデンティティベースポリシーを基に「どのサービスにアクセス可能か」を判断し、その上で「 3 日前に CloudWatch にアクセスした」「 RDS へのアクセスが可能だが追跡期間ではアクセスしていない」などを教えてくれます。

ここで、「最終アクセス時刻」は AWS サービスレベル での記録がほとんどであり、これまでは S3 のみがアクションレベルでの記録に対応していました。

今回のアップデートにより、以下の AWS サービスについてもアクションレベルでの記録に対応しました。

  • Amazon EC2
  • AWS IAM
  • AWS Lambda

「過去 X 日間の間に実績のあるアクション」「追跡期間中に一度も呼び出されていないアクション」などを簡単に可視化できます。

「 EC2 のフル権限を与えていたけど、必要なものにのみ絞りたいなぁ……」というケースにおいて、過去のアクセス実績を基にチューニングしていく、といった使い方ができ、役立ちそうですね。

補足

  • アクティビティ(最終アクセス時刻)はリアルタイムで反映されるわけではありません
    • IAM コンソールでは、通常 4 時間以内に反映されます
  • サービス情報の追跡期間は過去 400 日間です
  • 今回のアップデートで追加された EC2、IAM、Lambda のアクションの追跡は 2021年4月7日に始まっています
    • それ以前のアクティビティは記録されていません
  • 実行に失敗したアクションもアクティビティとして表示されます
  • アクションレベルの記録は CloudTrail に記録されたイベントがベースになっています

その他の注意事項については以下を参照してください。

Refining permissions in AWS using last accessed information - AWS Identity and Access Management

コンソールを確認してみた

早速どう変わっているか確認しましょう。

今回は IAM ロールの画面でアクセスアドバイザーを確認します。ちょっとアップデートしたよ、というメッセージが確認できます。

IAM_Management_Console-8877869

アクションレベルでの記録に対応しているサービスはサービス名がリンクになっており、詳細画面に遷移できます。

IAM_Management_Console-8877981

今回は IAM の詳細画面に遷移しました。アクションレベルで表示してくれています。

IAM_Management_Console-8878049

アクション名でフィルタリングしたり、アクセス実績の有無によってフィルタリングすることもできます。便利ですね。

IAM_Management_Console-8878117

AWS CLI で確認してみた

せっかくなので CLI でも確認してみます。

使用したバージョンは以下です。

% aws --version
aws-cli/2.1.33 Python/3.8.8 Darwin/19.6.0 exe/x86_64 prompt/off

大きく以下の流れで実行します。

  • aws iam generate-service-last-accessed-details を実行しジョブ ID を生成
  • aws iam get-service-last-accessed-details でジョブ ID の詳細を確認

以前似たようなことを以下エントリで行いましたので、あわせてご参照ください。

ジョブ ID の生成

コンソールで確認したものと同じロールを指定し、ジョブ ID を生成します。アクションレベルの記録を確認したい場合は、--granularity ACTION_LEVELを指定することを忘れないでください。

% aws iam generate-service-last-accessed-details \
  --granularity ACTION_LEVEL \
  --arn arn:aws:iam::000000000000:role/cm-chiba.yukihiro
{
    "JobId": "XXXXXXX-8787-2223-5254-d5ffa3f57fb1"
}

後続の処理のために、変数に格納しておきます。

% JOBID=`aws iam generate-service-last-accessed-details \
  --granularity ACTION_LEVEL \
  --arn arn:aws:iam::000000000000:role/cm-chiba.yukihiro\
  --output text`

サービスアクセス履歴の確認

先ほど生成したジョブ ID を引数に指定しコマンドを実行します。

イメージとしては以下のような結果が返ってきます。量が多すぎるので、 jq を使用して加工します。

aws iam get-service-last-accessed-details \
  --job-id 72bxxxa9-0939-fb81-1a23-exxxxx3460c5
{
    "JobStatus": "COMPLETED",
    "JobType": "SERVICE_LEVEL",
    "JobCreationDate": "2020-08-25T01:53:35.347000+00:00",
    "ServicesLastAccessed": [
        {
            "ServiceName": "Alexa for Business",
            "ServiceNamespace": "a4b",
            "TotalAuthenticatedEntities": 0
        },
        {
            "ServiceName": "IAM Access Analyzer",
            "LastAuthenticated": "2020-08-19T09:10:08+00:00",
            "ServiceNamespace": "access-analyzer",
            "LastAuthenticatedEntity": "arn:aws:iam::000000000000:role/cm-chiba.yukihiro",
            "LastAuthenticatedRegion": "ap-northeast-1",
            "TotalAuthenticatedEntities": 1
        },
---略---
        {
            "ServiceName": "Amazon S3",
            "LastAuthenticated": "2020-08-20T16:31:54+00:00",
            "ServiceNamespace": "s3",
            "LastAuthenticatedEntity": "arn:aws:iam::000000000000:role/cm-chiba.yukihiro",
            "LastAuthenticatedRegion": "ap-northeast-1",
            "TotalAuthenticatedEntities": 1,
            "TrackedActionsLastAccessed": [
                {
                    "ActionName": "CreateAccessPoint"
                },
                {
                    "ActionName": "CreateBucket",
                    "LastAccessedEntity": "arn:aws:iam::000000000000:role/cm-chiba.yukihiro",
                    "LastAccessedTime": "2020-08-19T05:19:00+00:00",
                    "LastAccessedRegion": "ap-northeast-1"
                },
                {
                    "ActionName": "CreateJob"
                },
---略---

例えば EC2 でアクセス実績のあるアクションのみ表示、としたい場合は以下のように指定します。

% aws iam get-service-last-accessed-details\
  --job-id $JOBID\
  --max-items 1000 \
 | jq -c '.ServicesLastAccessed[] | select( .ServiceNamespace == "ec2" ) | .TrackedActionsLastAccessed[] | select( .LastAccessedEntity !=null ) | [.ActionName, .LastAccessedTime]'
["AssociateRouteTable","2021-04-12T11:21:36+00:00"]
["AuthorizeSecurityGroupIngress","2021-04-12T10:57:04+00:00"]
["CreateSubnet","2021-04-12T11:21:25+00:00"]
["CreateVolume","2021-04-12T08:27:51+00:00"]
["DeleteVolume","2021-04-12T08:28:17+00:00"]
["DescribeAccountAttributes","2021-04-14T12:19:43+00:00"]
["DescribeAddresses","2021-04-14T12:19:45+00:00"]
["DescribeAvailabilityZones","2021-04-14T12:19:41+00:00"]
["DescribeCapacityReservations","2021-04-12T11:22:07+00:00"]
["DescribeCarrierGateways","2021-04-12T11:21:01+00:00"]
["DescribeClassicLinkInstances","2021-04-12T11:46:13+00:00"]
["DescribeCustomerGateways","2021-04-12T11:20:41+00:00"]
["DescribeDhcpOptions","2021-04-12T11:20:41+00:00"]
["DescribeEgressOnlyInternetGateways","2021-04-12T11:20:41+00:00"]
["DescribeFastSnapshotRestores","2021-04-12T08:27:46+00:00"]
["DescribeHosts","2021-04-14T12:19:40+00:00"]
---略---

アクションレベルでの記録に対応している AWS サービスの名前空間は以下です。必要に応じて.ServiceNamespace ==を変更してください。

  • ec2
  • iam
  • lambda
  • s3

さらに「過去 7 日間のうちにアクティビティがあるもの」と限定したい場合には、以下のように指定できます。

% AGO=7
DATE=`date -v-"$AGO"d +%Y-%m-%d`

aws iam get-service-last-accessed-details --job-id $JOBID --max-items 1000 \
 | jq -c '.ServicesLastAccessed[] | select( .ServiceNamespace == "ec2" ) | .TrackedActionsLastAccessed[] | select(( .LastAccessedTime !=null) and (.LastAccessedTime > "'$DATE'" )) | [.ActionName, .LastAccessedTime]'
["DescribeAccountAttributes","2021-04-14T12:19:43+00:00"]
["DescribeAddresses","2021-04-14T12:19:45+00:00"]
["DescribeAvailabilityZones","2021-04-14T12:19:41+00:00"]
["DescribeHosts","2021-04-14T12:19:40+00:00"]
["DescribeInstanceStatus","2021-04-14T12:19:45+00:00"]
["DescribeInstanceTypes","2021-04-14T12:19:44+00:00"]
["DescribeInstances","2021-04-14T12:19:44+00:00"]
["DescribeKeyPairs","2021-04-14T12:19:41+00:00"]
["DescribeLaunchTemplates","2021-04-14T12:19:41+00:00"]
["DescribePlacementGroups","2021-04-14T12:19:41+00:00"]
["DescribeRegions","2021-04-14T10:57:40+00:00"]
["DescribeSecurityGroups","2021-04-14T12:19:41+00:00"]
["DescribeSnapshots","2021-04-14T12:19:40+00:00"]
["DescribeTags","2021-04-14T12:19:43+00:00"]
["DescribeVolumeStatus","2021-04-14T12:19:41+00:00"]
["DescribeVolumes","2021-04-14T12:19:41+00:00"]

いろいろ条件や表示する項目を変えたり応用が効くと思いますので、ご活用ください。

アクセスアドバイザーも活用して最小権限を目指そう

アクセスアドバイザーによるアクションレベルの記録が、 EC2、IAM、Lambda にも対応したことを確認しました。

先日は IAM Access Analyzer が「過去のアクティビティをベースにしたポリシーの生成」に対応しました。

できることは IAM Access Analyzer の方が多いですが、アクセスアドバイザーはコンソールで開くだけ、というお手軽さがあります。両者を活用して、適切な権限を探っていきましょう。「とりあえずフルアクセス」はリスクが大きいですよ。

以上、千葉(幸)がお送りしました。

参考