現場で泥水をすすってきたエンジニア諸君、お疲れ様。CISSPとして数々のインシデント現場を見てきたが、結局のところ、「攻撃者は最も脆い場所から入る」という原則は変わらない。そして、その「最も脆い場所」の筆頭が、開発者のPCやCI/CDパイプラインに置きっぱなしの『AWS IAMアクセスキー』だ。
今日は、教科書的な「IAMポリシーを最小権限にしましょう」といった綺麗事ではなく、「明日、君たちのアクセスキーがGitHubの公開リポジトリに流出したとしても、即座に被害をゼロにするための自動防衛ライン」の作り方を伝授する。
—
1. なぜ「キーの管理」は破綻するのか?
多くの現場で、アクセスキーは「一度作ったら作りっぱなし」になっている。なぜか? 運用が面倒だからだ。ローテーションしようとするとアプリケーション側の環境変数を書き換える必要があり、ダウンタイムを恐れて放置される。
攻撃者は、GitHubの検索機能や、S3バケットの公開設定の不備を突くスキャナーを24時間稼働させている。君たちがうっかり git push した瞬間に、そのキーは世界中のボットネットの手に渡り、数分後にはマイニングサーバーが立ち上がるか、RDSのデータが人質に取られる。
「キーを漏らさない」という精神論は捨てろ。
「漏れることを前提に、有効期限を極限まで短くし、古いキーを自動で葬る」仕組みこそが、真の要塞化だ。
—
2. 自動ローテーションの実装(Pythonによる解決策)
AWS CLIを叩くシェルスクリプトも悪くないが、柔軟性とエラーハンドリングを考えるとPython(boto3)一択だ。以下のスクリプトは、IAMユーザーに対して「90日経過したキーを無効化・削除する」ための骨子となる。
import boto3
from datetime import datetime, timezone
# IAMクライアントの初期化
iam = boto3.client('iam')
def rotate_iam_keys(user_name):
# ユーザーのアクセスキー一覧を取得
keys = iam.list_access_keys(UserName=user_name)['AccessKeyMetadata']
for key in keys:
create_date = key['CreateDate']
# 経過日数を計算
age = (datetime.now(timezone.utc) - create_date).days
# 90日経過したキーは問答無用で非アクティブ化
if age > 90 and key['Status'] == 'Active':
print(f"警告: キー {key['AccessKeyId']} は {age} 日経過しています。無効化します。")
iam.update_access_key(
AccessKeyId=key['AccessKeyId'],
Status='Inactive',
UserName=user_name
)
# 必要であれば iam.delete_access_key() で削除まで自動化する
# ただし、手動確認プロセスを挟むのが安全
if __name__ == "__main__":
rotate_iam_keys('deploy-user')
実務のポイント
- 削除のタイミング:
Inactiveにして即Deleteすると、デプロイが止まる可能性がある。まずはInactiveにして1週間放置し、システムが落ちないか監視する「猶予期間」を設けるのが、現場で怒られないためのコツだ。 - 通知: このスクリプトをAWS Lambdaに載せ、実行結果をSlackに飛ばすようにせよ。誰が、いつ、どのキーを無効化したかが可視化されるだけで、チームのセキュリティ意識は劇的に変わる。
—
3. 「キーを使わない」という最強の選択肢
そもそも、アクセスキーをコードや設定ファイルに書いている時点で負けだ。EC2やLambda上で動くアプリケーションであれば、「IAMロール」を絶対に利用しろ。
IAMロールを使えば、アクセスキーそのものが存在しない。AWSが一時的な認証情報を自動的に注入し、短時間でローテーションしてくれる。もし君が「ローカル開発環境で使うから」と言い訳をしているなら、それは設計の敗北だ。
- ローカル開発時:
AWS_PROFILEを切り替えて、aws-vaultやSSOを利用すること。 - CI/CDパイプライン: GitHub Actionsなら
configure-aws-credentialsを使い、OIDC(OpenID Connect)経由で一時的な認証情報を取得しろ。これならアクセスキーをGitHubに保存する必要は一生なくなる。
—
4. 最後に:セキュリティは「泥臭い継続」だ
今回提示した自動化スクリプトは、あくまで「最低限の防波堤」に過ぎない。
本当の要塞化とは、こうしたツールを導入した上で、「アクセスキーの漏洩を検知した瞬間に、全権限を剥奪するパイプライン」を構築することだ。AWS Configを使って、「アクセスキーの作成・変更」イベントをトリガーに、即座に該当キーを無効化するEventBridgeルールを組んでおけば、攻撃者がキーを盗んだ次の秒には無力化できる。
セキュリティは、一度設定して終わりではない。常に攻撃者の視点に立ち、「自分ならここを突く」という嫌な想像力を働かせ続けることだ。
もし君たちが明日からこの運用を始めるなら、まずは「誰が、いつ、何のキーを発行したか」の棚卸しから始めろ。使われていない古いキーを一つ消すだけでも、君たちのシステムは確実に強くなる。
健闘を祈る。何かあればまた相談してくれ。
コメント