技術ブログ

IAMアクセスキーのローテーション漏れを「80/85/90日」で段階通知する(EventBridge Scheduler / Lambda / SNS / DynamoDB)

AWSアカウント運用では、IAMユーザーのアクセスキーが長期間ローテーションされずに残ってしまうことがあります。
本記事では、アクセスキーの年齢を毎日チェックし、80 / 85 / 90日のタイミングで段階的にメール通知する仕組みを、EventBridge Scheduler + Lambda + SNS + DynamoDBで構築した方法をまとめます。

この記事で実現すること

  • EventBridge Scheduler を使って 毎日 9:00(JST)に定期実行
  • IAMのアクセスキーを走査し、以下の条件のものだけを通知対象にする
    • Status = Active のアクセスキーのみ
    • IAMユーザー名に「@」を含むもののみ(=開発側アカウントを除外)
  • 経過日数に応じて段階通知
    • 80日:事前周知
    • 85日:リマインド
    • 90日:至急
  • 同じキーは同じ段階で1回だけ通知(DynamoDBで通知済み管理)
  • メールの件名/本文に環境名(ENV_NAME)アカウントIDを入れて、どの環境の通知か分かるようにする

全体構成

  • EventBridge Scheduler:毎日9:00(JST)に起動
  • Lambda:IAMユーザー/アクセスキーを走査し、段階判定してSNSへ通知
  • SNS(Email):運用チームMLなどへメール送信
  • DynamoDB:通知済み段階(80/85/90)を保存し、重複通知を防止

1. DynamoDB(通知済み管理テーブル)の作成

通知の重複を避けるため、キーごとに「どこまで通知したか」を記録します。

  • テーブル名:AccessKeyPreNoticeState
  • パーティションキー:pk(String)
    • 例:user@example.com#AKIAxxxxxxxxxxxx

保存する主な属性(例)

  • last_notified_stage:80/85/90 のどこまで通知したか
  • last_notified_at:最終通知時刻
  • age_days:通知時点の経過日数
  • status:Active/Inactive

2. SNS(メール通知先)の準備

SNSで Standard トピックを作成し、メール購読を追加します。

  • トピックARN例:arn:aws:sns:us-east-1:123456789012:next-iam-accesskey-notify
  • 購読:ops-notify@example.com(例)
  • 確認メールを承認して Confirmed にする

3. Lambda(80/85/90の段階通知ロジック)

Lambdaでは iam:ListUsersiam:ListAccessKeys を使ってアクセスキーの情報を取得し、以下を行います。

3-1. 通知対象の条件

  • IAMユーザー名に @ を含む(例:user@example.com
  • アクセスキーの StatusActive
  • 経過日数が 80 / 85 / 90 に到達

@ を含まないユーザー(例:deploy-userservice-user)は通知対象外にしています。

3-2. 段階通知の考え方

  • 経過日数が 96日などの場合、通知段階は「最大段階(90日)」とし、同日に 80/85/90 を連続送信しないようにします。
  • DynamoDBの last_notified_stage を見て、段階が進んだときのみ通知します。

3-3. メールの分かりやすさ

Lambda内で STS を使って実行アカウントIDを取得し、本文に入れます。さらに環境名は環境変数 ENV_NAME として持たせます。

  • ENV_NAME 例:本番(XXXX) / ステージング(XXXX) / テスト(XXXX)

4. EventBridge Scheduler(毎日 9:00 JST)

Scheduler の設定例:

  • タイムゾーン:Asia/Tokyo
  • cron:0 9 * * ? *
  • ターゲット:上記Lambda

JST 9:00 は UTC 0:00 に相当するため、CloudWatchログ等はUTC時刻で見えることがあります。

5. Lambda実行ロールの最小ポリシー例

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "IamRead",
      "Effect": "Allow",
      "Action": ["iam:ListUsers", "iam:ListAccessKeys"],
      "Resource": "*"
    },
    {
      "Sid": "SnsPublish",
      "Effect": "Allow",
      "Action": "sns:Publish",
      "Resource": "arn:aws:sns:us-east-1:123456789012:next-iam-accesskey-notify"
    },
    {
      "Sid": "DdbState",
      "Effect": "Allow",
      "Action": ["dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem"],
      "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/AccessKeyPreNoticeState"
    },
    {
      "Sid": "Logs",
      "Effect": "Allow",
      "Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
      "Resource": "*"
    }
  ]
}

6. 運用でハマりがちなポイント

  • Lambdaタイムアウト:IAMユーザー数が多いと時間がかかる
    • タイムアウト:30〜60秒メモリ:256MB程度

で安定しやすい。

  • 通知が来ない:DynamoDBの通知済み記録により、同じ段階では再通知されない(仕様)
  • 環境が分からないENV_NAMEAccount ID を必ず本文/件名に入れると誤対応が減る

まとめ

EventBridge Schedulerで毎日定期実行し、LambdaでIAMアクセスキーをチェック、SNSでメール通知することで、アクセスキーのローテーション漏れを運用で拾えるようになります。
特に、80/85/90日で段階的に通知し、Activeかつ「@ありユーザーのみ」に絞ることで、顧客要望(開発側アカウントを除外)にも対応できます。

ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。

  • 選考ではありません
  • 履歴書不要
  • 技術の話が中心
  • 所要時間30分程度
  • オンラインOK

エンジニアと話してみる