0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

よくある「IAMロール=ヘルメット」の例えは微妙だった話

Last updated at Posted at 2025-11-26

はじめに

アクセスキー前提の講座に違和感を覚えたので整理しました。

今回は、とあるオンライン講座で教えられていた IAM の権限まわりの扱いに違和感を覚えたので、
自分なりに調べて整理した内容をまとめます。

テーマはざっくり言うと、

・IAMユーザー+アクセスキー前提のやり方って、今のAWSのベストプラクティスと合ってるの?

・よくある『IAMロール=ヘルメット』の例え、厳密にはズレてない?

以下で詳しく解説します。

前提

受講した講座の前提はこんな感じでした。

ローカルのマシンで Terraform を使って AWS リソースを作成する。
そのために「IAMユーザーのアクセスキーを発行して、環境変数に認証情報を登録しましょう」。

つまり、
1. IAMユーザーを作る
2. アクセスキー / シークレットアクセスキーを発行する
3. ローカルのシェルで

bash
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...

4. Terraform はこの環境変数からアクセスキーを読み取り、その権限の範囲内でリソース操作を行う

という流れです。

一見「まあ、そういうものかな」と思いがちですが、
今のベストプラクティスから見ると、かなり大きなセキュリティ的な問題を含んでいます。

アクセスキー方式のどこが危ないのか

1. アクセスキーは基本「無期限」

IAMユーザーのアクセスキーは 削除・ローテーションするまで有効 です。
つまり、基本的に有効期限がありません。

・一度流出したら、そのキーを消すまで攻撃者がずっと使える

・ローテーション(作り直し)も手作業になりがちで、「面倒だから放置」が起きやすい

一方、今のAWSが推している考え方は

・一時クレデンシャル(セッション)で短時間だけ使う

・期限が切れたら STS / SSO 経由で取り直す

というものです。

なので、「長生きする固定キー」を前提にする時点で、その鍵そのものがリスクになりやすい構成になっています。

2. キーが漏れやすい(人間の運用で事故る)

アクセスキーを 環境変数で持つ やり方には、実は落とし穴がいっぱいあります。

・.zshrc / .bashrc / .profile に書いて Git にコミットしてしまう

・.env ファイルに書いて、そのままリポジトリに上げてしまう

・env / printenv の出力をログやQiita記事にコピペしてしまう

・シェルの履歴に export AWS_SECRET_ACCESS_KEY=... が残る

・スクリーン共有中にターミナルをそのまま見せてしまう

・一度 GitHub に上がると、GitHub の Secret Scanning より先に攻撃者のスクレイパーに拾われる

「環境変数だから安全」というわけではなく、人間のちょっとした運用ミスで普通に漏れます。

じゃあ、今のベストプラクティスは何?

ざっくりまとめると、AWSが公式ドキュメントなどで言っているのはこういう方針です:

・人間ユーザー・ワークロードともに
→ IAMロール+一時クレデンシャルでアクセスする

・組織的に管理するなら
→ IAM Identity Center(旧SSO)でアカウントと権限を一元管理する

・IAMユーザーは
→ ルート・レガシー・どうしてもロールにできない特殊ケースだけに限る(それ以外は Identity Center や外部IdP+ロールを使う)

ローカルから Terraform を叩くときの「今っぽい構成」

典型的なパターンはこんな感じ:

・人間は Identity Center(SSO)+ロール

・IAM Identity Center でユーザー & Permission Set(開発者ロール)を作る

・ローカルで AWS CLI を SSO モードで設定する

bash
aws configure sso
# 対話形式で SSO start URL, SSO region, アカウント、ロールを選ぶ

・Terraform では、その SSO プロファイルを使って
さらに Terraform 専用ロールを AssumeRole する

hcl
provider "aws" {
  region  = "ap-northeast-1"
  profile = "dev-sso"  # aws configure sso で作ったプロファイル名

  assume_role {
    role_arn     = "arn:aws:iam::123456789012:role/TerraformRole"
    session_name = "terraform-session"
  }
}

こうしておけば、

・ローカルには 長期アクセスキーを保存しない

・人間は Identity Center ログイン時に認証+MFA

・Terraform は TerraformRole に定義した最小限の権限でだけ動く

という構成にできます。

ここから本題:「IAMロール=ヘルメット」比喩の違和感

「ロールとかポリシーとか色々わからん!なんかいい例えないのか?」

と思って調べてみると
よくある説明で、IAMロールはこう例えられます。

ロール = ヘルメット
ポリシー = ヘルメットに貼ってあるバッジ
ユーザー = そのヘルメットをかぶる人

この比喩で IAM を説明する記事がいっぱい出てきました。
雰囲気を掴むには悪くないんですが、微妙に誤解を生みやすいと感じています。

なぜかというと、この例えだと:

・「ヘルメット(ロール)を誰かに貸している」

・「ロールの持ち主が移動している」

ようなイメージになりがちだからです。

ロールとポリシーの関係を理解するには便利なのですが、実際の IAM の世界では、

・ロールは誰かの「所有物」ではなく、できること(許可ポリシー)をまとめた定義

・誰かがロールを「借りたり返したり」しているわけでもない

・そのロールとして振る舞う『一時的な状態(セッション)』 が発行されるだけ

という構造になっています。

ここが 「ヘルメット=ロール」だけの例えだと抜け落ちてしまうポイントです。


正しいイメージ:Principal / Role / Session の3つ

自分の中でしっくり来た整理は、次の3つに分けて考えることでした。

1. Principal(プリンシパル)
→ AWS に対して「私はこれです」と名乗っている実体

例:
・Identity Center 経由でログインした人間

・GitHub Actions のジョブ

・EC2 / ECS / Lambda などのAWSリソース

2. Role(ロール)
→ 「どういう権限で振る舞うか」の役割テンプレ

・DeveloperRole

・TerraformRole

・GitHubActionsRole

など。

ロール自体には期限はなく、削除しない限り存在し続けます。

3. Session(セッション)=一時パスポート
→ Principal が「特定の Role として振る舞うための、一時的なクレデンシャル」

・STS AssumeRole や SSO ログインの結果として発行される

・AccessKeyId / SecretAccessKey / SessionToken / 有効期限 がセット

・時間が来たら失効するので、また取り直し必要

この3つで見ると、

「ロールを貸し借りしている」のではなく、

「プリンシパルが、そのロールとして振る舞う“セッション”を持っている」

という状態であることが分かります。

入国管理官の例えで整理してみる

ここで、さっきの話を「入国管理」のストーリーとして並べ替えてみます。

登場人物

・🧑 太郎:ローカルで Terraform を叩くエンジニア(Principal)

・🤖 Terraform ロボ:太郎の指示通りに AWS リソースを作るツール(Principalではない)

・🏢 ロールたち:

  ・DeveloperRole:開発者用のロール

  ・TerraformRole:インフラ構築専用のロール

・🛂 AWS STS 入国管理官さん:AssumeRole を審査して一時パスポートを発行するサービス

・🎫 セッション:ロールとして振る舞うための一時パスポート

ストーリー
1. 太郎が aws sso login でログインする
→ Identity Center から STS 入国管理官さんに依頼が行く
→ 「この人を DeveloperRole として AWS に入れてください」
→ 入国管理官さんが DeveloperRole セッション(一時パスポート)を発行

この時点での Principal は:
「DeveloperRole のセッションを持った太郎」

2. 太郎が terraform apply を実行する
Terraform の設定にはこう書いてある:

hcl
provider "aws" {
  region  = "ap-northeast-1"
  profile = "dev-sso"

  assume_role {
    role_arn     = "arn:aws:iam::123456789012:role/TerraformRole"
    session_name = "terraform-session"
  }
}

Terraform ロボ:
「今ぼくは DeveloperRole の一時パスポートを使ってる。
でも設定を見ると『TerraformRole として作業しろ』と書いてある。
じゃあ入国管理官さんに、TerraformRole のパスポートをお願いしよう。」

3. Terraform ロボが AssumeRole(TerraformRole) を実行する
入国管理官さんが2つチェックする:

・DeveloperRole に「TerraformRole を Assume してよい」権限があるか

・TerraformRole の trust policy に「DeveloperRole からの AssumeRole を許可する」と書いてあるか

両方OKなら、入国管理官さん:
「はい、TerraformRole として振る舞える一時パスポートを発行します。」

ここで TerraformRole セッション が発行されます。

4. Terraform ロボは以降、TerraformRole セッションで AWS にアクセスする
→ VPC/ECS などの作成・更新は TerraformRole のポリシーの範囲内だけ で実行される。

ここでポイントなのは:
・ロールそのもの(DeveloperRole / TerraformRole)はできることを定義した 「役職テンプレ」 でしかない

・誰かに「貸されて」移動するわけではない

・実際に動いているのは
「特定のロールとして振る舞うセッションを持った Principal」

ということです。


ここまでを踏まえて、ヘルメット比喩を少しだけ修正すると、かなりしっくり来ます。
・ロール = 会社ので決められている 「役職ヘルメットをかぶっている人の役割」

・現場作業員ヘルメット

・現場監督ヘルメット

・管理者ヘルメット

・Principal = それをかぶる可能性のある人・ジョブ・リソース

・セッション =
「誰かがそのヘルメットをかぶって、決められた時間だけ働いている状態」
ヘルメットを取ったら仕事はできない

つまり、
・❌ ロール(ヘルメット)を貸す / 持ち主が変わる

・✅ Principal が、一定時間だけそのロールをかぶって振る舞う(セッションを持つ)

というのが、IAMの実際のモデルに近いイメージです。

まとめ:講座の構成を「今風の話」にアップデートするなら

オンライン講座が教えていたのは:

IAMユーザーを作って、アクセスキーを環境変数に入れて、Terraform から直接使う

という「昔ながらの」やり方でした。

それを、今のAWSの考え方・IAMのモデルに合わせて言い換えると、
こんな風にアップデートできます。

・人間は Identity Center でログインし、DeveloperRole のセッション をもらう

・Terraform はそのセッションを使って、TerraformRole を AssumeRole する

・実際に動いているのは 「ロールを振る舞うことのできるセッションを持った Principal」

・長期アクセスキーを前提にせず、一時クレデンシャル+ロール前提で設計する

こうしておくと、

・セキュリティ的にも安心(キーが長生きしない)

・権限分離(人間用 / Terraform用 / 本番用)がしやすい

・長期アクセスキーを前提にせず、一時クレデンシャル+ロール前提で設計する

という現代のベストプラクティスに沿った設計ができます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?