目次
2 章

IAM — ユーザー、グループ、ロール、ポリシー

AWS で誰として働くかを定める IAM の4要素 — ユーザー · グループ · ロール · ポリシー — を一度に整理します。JSON ポリシーの文法と AssumeRole の本質、そして小さなチームでも通用する権限設計パターンまで扱います。

第1章 AWS 入門 の最後で「ルートユーザーで働かないようにしよう」と述べました。では、誰として働けばよいのでしょうか。答えは IAM (Identity and Access Management) で作ったユーザーとロールです。本章は登録直後にまず通るべきセットアップの出発点です。

IAM はグローバルサービスです。どのリージョンでコンソールを開いても同じユーザー / ロール / ポリシーが見えます。そして無料です。追加費用なしでユーザーを無制限に作れます。そのため AWS に初めて入ると、最初に出会うべきサービスです。

本章では IAM の4要素を一度に整理し、運用で通用する権限設計の核心パターンまで見ていきます。ここで作ったユーザーとロールは 第4章 CLI と SDK から絶えず登場し、第6章 セキュリティ基本 で MFA と最小権限によってもう一段固められます。

大きな絵 — IAM の4要素 #

要素何か誰が / 何が使うか
User (ユーザー)人ひとり、またはマシン1台に紐づく永続的な認証情報コンソールログイン、アクセスキー
Group (グループ)ユーザーの束グループにポリシーを付けると中のユーザー全員に適用
Role (ロール)一時的に借りて使う認証情報EC2、Lambda、他のアカウントのユーザーなど
Policy (ポリシー)何を許可 / 拒否するかの JSON ドキュメント上の3つに付いて権限を定義

核心は ポリシーがすなわち権限だということです。ユーザー / グループ / ロールは権限を入れる器であり、その中のポリシーが本当に何ができるかを決定します。

Policy — JSON で権限を書く #

ポリシーは JSON ドキュメントです。この形に慣れることが IAM 学習の80%です。

最も単純なポリシー
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

読むと、s3:GetObject アクションを my-bucket のすべてのオブジェクト(*)に対して許可するという意味です。各キーの意味は次のとおりです。

キー何か
Versionポリシー文法のバージョン。常に 2012-10-17
Statement権限ルールの配列
EffectAllow または Deny
Actionどの API 呼び出しを許可 / 拒否するか — <サービス>:<アクション>
Resourceどのリソースに — ARN で
Condition (オプション)追加条件 — IP、時間、タグなど

Action の形式 #

s3:GetObject のように <サービス>:<アクション> の形式です。ワイルドカードも使えます。

Action ワイルドカードの例
"Action": "s3:Get*"          // s3 のすべての Get アクション
"Action": "s3:*"             // s3 のすべてのアクション
"Action": ["s3:GetObject", "s3:PutObject"]  // 配列で複数

Resource の形式 #

ARN で書きます。ARN の形は 第1章 で見ました。

Resource の例
"Resource": "arn:aws:s3:::my-bucket"           // バケット自体
"Resource": "arn:aws:s3:::my-bucket/*"         // バケット内のすべてのオブジェクト
"Resource": "arn:aws:s3:::my-bucket/uploads/*" // 特定の prefix だけ
"Resource": "*"                                // すべてのリソース (危険)

Condition — 最も強力な制御手段 #

条件がポリシーの本当の力を作る部分です。

会社の IP からだけ許可
{
  "Effect": "Allow",
  "Action": "s3:*",
  "Resource": "arn:aws:s3:::my-bucket/*",
  "Condition": {
    "IpAddress": {
      "aws:SourceIp": ["203.0.113.0/24"]
    }
  }
}
MFA がオンのセッションでだけ許可
{
  "Effect": "Allow",
  "Action": "iam:*",
  "Resource": "*",
  "Condition": {
    "Bool": { "aws:MultiFactorAuthPresent": "true" }
  }
}

よく使う条件キーは次のとおりです。

キー何か
aws:SourceIpリクエスト IP
aws:MultiFactorAuthPresentMFA の使用有無
aws:RequestTag/<key>作るときのタグ
aws:ResourceTag/<key>リソースのタグ
aws:CurrentTime時間

Allow / Deny の評価順序 #

複数のポリシーが重なると、IAM は次の順序で決定します。

評価順序
1) 明示的な Deny が一つでもあれば → 拒否 (終了)
2) 明示的な Allow が一つでもあれば → 許可
3) どちらもなければ → 拒否 (デフォルト)

Deny が常に勝ちます。 そのため「このユーザーは prod リソースだけは絶対に触れないように」のようなガードレールは Deny で書きます。許可ポリシーの隣に Deny を付けるパターンです。

User — 人 / マシンのための永続的な認証情報 #

IAM ユーザーはメールアドレスではなく別途の ID です。コンソールログイン URL も別に生成されます。

IAM ユーザーのコンソール URL
https://<アカウントID>.signin.aws.amazon.com/console
または
https://<アカウントエイリアス>.signin.aws.amazon.com/console

ユーザーを作る #

コンソールで IAM → Users → Add users へ入ります。

項目何か
ユーザー名メールアドレスではありません。curtisdev-bot のような識別子
コンソールアクセスパスワード — 人向け
プログラムによるアクセスアクセスキー — CLI / SDK 向け(第4章 CLI と SDK)
権限グループに追加、ポリシーを直接アタッチ、または他のユーザーからコピー

ベストプラクティスはユーザーにポリシーを直接付けないことです。グループを通じて付けます。理由は次の節で扱います。

アクセスキー — ユーザーが持つ最も危険な認証情報 #

アクセスキーは2行の文字列です。

アクセスキーの形
Access Key ID:     AKIAIOSFODNN7EXAMPLE
Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY

この2つがあれば、そのユーザーのすべての権限を行使できます。そのため次のことを守ります。

  • ユーザー1人あたりアクセスキーは最大2個です(ローテーション中に一時的に2つ共存)。
  • 絶対に git やコードに入れません(第1章 のルートキー漏洩の事例)。
  • 90日ごとにローテーションします(第6章 セキュリティ基本 で詳しく扱います)。
  • できればユーザーのアクセスキーの代わりにロール(Role)を使います。

Group — ユーザー管理の単位 #

グループはユーザーを束ねる単位です。グループにポリシーを付けると、そのグループのすべてのユーザーに自動的に適用されます。

グループ設計のよくある形
Admins         → AdministratorAccess
Developers     → PowerUserAccess + (IAM 拒否ポリシー)
ReadOnly       → ReadOnlyAccess
Billing        → 決済コンソールへのアクセスだけ

なぜユーザーに直接付けずグループに付けるのか #

新しい開発者が入社したとしましょう。

ユーザー直接モデルでは、既存の開発者一人ひとりに個別にポリシーを付けます。そのうち「あの人に1週間前に追加したポリシーは何だったか」となって漏れが生じ、時間が経つと開発者ごとに権限が微妙に異なっていきます。

グループモデルでは、Developers グループに追加するだけで終わりです。権限の変更はグループのポリシーだけを変えれば全員に一貫して適用され、監査と点検もグループ単位できれいです。

ルールは次のとおりです。IAM ユーザーにはインラインポリシーや直接アタッチのポリシーを禁止し、すべての権限はグループまたはロールで与えます。

Role — 一時的に借りて使う認証情報 #

Role は誰かの認証情報ではなく、何でも一時的に借りて使える認証情報です。永続的なパスワードやアクセスキーがありません。代わりに誰かまたは何かが AssumeRole という呼び出しをすると、AWS が一時的な認証情報(1時間 ~ 12時間有効)を発行してくれます。

これが IAM の最も重要な点です。最初は難しいですが、慣れると IAM の本当の力が見えてきます。

Role が実際に使われる場合 #

シナリオ誰が AssumeRole するか
EC2 が S3 にアクセスEC2 インスタンス (自動で)
Lambda が DynamoDB に書き込みLambda (自動で)
ECS Task が他のサービスを呼び出しTask (自動で)
他の AWS アカウントのユーザーがこのアカウントの一部リソースにアクセスそのユーザーが明示的に
GitHub Actions が ECR に pushOIDC で GitHub Actions
一時的な権限昇格 (Break-glass)ユーザーが明示的に

EC2 / Lambda / ECS のような環境では、AWS が自動的に AssumeRole をして認証情報をインスタンスに流してくれます。コードはただ SDK を呼べばよいだけです。アクセスキーを扱う必要がありません。これが核心です。

ロールの2つのポリシー #

ロールには2種類のポリシーが付きます。

1) Trust Policy (信頼ポリシー) — 誰がこのロールを借りられるかを定めます。

EC2 が借りられるロール
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": { "Service": "ec2.amazonaws.com" },
    "Action": "sts:AssumeRole"
  }]
}

Principal 項目に誰が入ります — サービス、他のアカウント、ユーザー、OIDC provider などです。

2) Permission Policy (権限ポリシー) — 借りた後に何ができるかを定めます。

ロールの中で S3 読み取りを許可
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::my-bucket/*"
  }]
}

EC2 インスタンスプロファイルの流れ #

EC2 → S3 の認証情報の流れ
[EC2 インスタンス]
   │ 1) インスタンスメタデータ (169.254.169.254)に認証情報を要求
[IAM]
   │ 2) インスタンスに付いたロールの一時認証情報を発行
[EC2 の中の SDK]
   │ 3) 認証情報で S3 を呼び出し
[S3]

EC2 の中のコードはアクセスキーを知りません。boto3 や aws-sdk が自動でメタデータから認証情報を取り出して使います。キー漏洩の事故を根本的に減らしてくれます。

管理ポリシー vs インラインポリシー #

ポリシーは作り方でさらに分かれます。

種類何か推奨
AWS 管理AWS が作っておいたもの (例: AdministratorAccessReadOnlyAccess)入門 / 標準ロール
カスタマー管理自分が作ったポリシー。複数のユーザー / ロールに再利用可能運用標準 — 推奨
インライン一つのユーザー / グループ / ロールにだけ直接付与したもの非推奨 — 再利用できない、追跡が難しい

よく使う AWS 管理ポリシー #

名前何か
AdministratorAccessすべての権限。ルートの次に危険
PowerUserAccessIAM を除くほぼすべての権限
ReadOnlyAccessすべてのサービスの読み取りだけ
Billing決済コンソール
<Service>FullAccess (例: AmazonS3FullAccess)一つのサービスの全部
<Service>ReadOnlyAccess一つのサービスの読み取り

最初は管理ポリシーで始めて、徐々に絞ってカスタマー管理へ移すのが一般的な流れです。

運用の権限設計 — 通用するパターン #

小さなチームでも通用する権限設計の骨格です。

1) グループ4 + ロール3 #

単位名前何か
グループAdminsAdministratorAccess (MFA 強制)
グループDevelopersPowerUserAccess + IAM 拒否
グループReadOnlyReadOnlyAccess
グループBilling決済 / コスト
ロールEC2-AppRoleアプリが使うロール (S3、RDS など)
ロールLambda-WorkerRoleラムダ用
ロールCICDRoleGitHub Actions / CodeBuild が借りる

2) 権限境界 (Permission Boundary) #

「この IAM ユーザーは何をしてもこの限度の中だけで」を定める保護膜です。新人開発者が新しいポリシーを作って自分の権限を増やす事故を遮断します。

パターン
Developers グループ → PowerUserAccess
   ↓ そしてすべてのユーザーに権限境界を付与
権限境界 → "DevOnly" — dev/* リソースだけ作れる

3) MFA 強制 #

ルートとすべての IAM ユーザーに強制します。強制ポリシーの形は 第6章 セキュリティ基本 で詳しく扱います。

4) ユーザー ↔ ロールの分離 #

ユーザーは人だけ、マシンはすべてロールにします。これが明確であればアクセスキーの事故はほとんど起こりません。

5) 条件でガードレール #

開発者が prod-* タグのリソースを触れないように
{
  "Effect": "Deny",
  "Action": "*",
  "Resource": "*",
  "Condition": {
    "StringEquals": { "aws:ResourceTag/env": "prod" }
  }
}

タグを一貫して使えば、ポリシー1行で環境分離ができます(第3章 コスト管理 のタグ戦略と同じ土台です)。

ポリシーシミュレーター — 検証ツール #

IAM Policy Simulator(policysim.aws.amazon.com)は、ユーザー / グループ / ロールに対して「このアクションは可能か」をシミュレーションしてくれるツールです。ポリシー変更後に意図したとおりになったかを確認するのに使います。

流れ
1) ユーザーまたはロールを選択
2) シミュレーションするアクションを選択 (例: s3:DeleteObject)
3) リソース ARN を入力 (任意)
4) "Run Simulation" → Allowed / Denied とどのポリシーが影響したか

第6章 セキュリティ基本 の IAM Access Analyzer も併せて点検に役立ちます。

IAM ユーザーを作る — 実習 #

ここまで来たら、実際に IAM ユーザーを一人作っておくことをおすすめします。第4章 CLI と SDK からはこのユーザーとロールが必要です。

実習の手順
1. コンソール → IAM → Users → Add users
2. ユーザー名: 自分の名前 (例: curtis)
3. Console access: 有効化、パスワード自動生成
4. Attach policies directly: AdministratorAccess (学習用 — 後で絞る)
5. 作った直後 → MFA を即座に有効化 (強制方法は6章)
6. Access keys: CLI 用に1個だけ発行
7. .csv ダウンロード — Secret はこの画面でだけ見える

この直後に 第3章 コスト管理第6章 セキュリティ基本 へ進みます。

よく出会う落とし穴 #

  • ユーザーにポリシーを直接アタッチ — 10人までは大丈夫に見えますが、30人で権限が微妙に異なり始めます。侵入時に誰の権限がどこまでなのか把握できません。グループに集めます。
  • Resource: "*" の乱発 — 最初は楽ですが、侵入時に被害範囲が無限大です。可能なすべてのロールで ARN に絞ります。
  • インラインポリシー — 一度に打ち込むときは速いですが、1ヶ月後に誰が追加したポリシーか分からず再利用もできません。名前が付いてバージョンが管理されるカスタマー管理ポリシーへ移します。
  • アクセスキーを EC2 の中に直接付与する — EC2 → S3 の認証情報をアクセスキーで解決するコードはインスタンスプロファイル(ロール)へ移す必要があります。キーのローテーションを忘れると事故が永遠に潜在します。
  • 「テストで作ったユーザー」がそのまま — 退職者のアクセスキー、一度作って忘れたボットユーザーが残ります。30日 / 90日未使用のユーザーは自動無効化 / 削除ポリシーを作り、IAM Credential Report で一目で確認します。
  • ルートユーザーにアクセスキー第1章 の最もよくある事故です。ルートはコンソールと MFA だけ、アクセスキーは絶対に作りません。

練習問題 #

  1. §「Allow / Deny の評価順序」を根拠に、あるユーザーに AdministratorAccess が付いているのに特定のバケットのオブジェクトを消せないようにするには、どの Statement を追加すべきかを JSON の断片で書いてみましょう。
  2. §「ロールの2つのポリシー」で Trust Policy と Permission Policy がそれぞれ何を決定するかを一文ずつ書き、第4章 CLI と SDKrole_arn + source_profile プロファイルがこのうちどちらの流れを CLI で再現するかを結びつけてみましょう。
  3. 自分が運用する小さなチームを想定して §「グループ4 + ロール3」の表を自分の環境に合わせて書き直してみましょう。そのうちマシン用のロールを一つ選び、そのロールが 第6章 セキュリティ基本 の「ユーザー = 人、マシン = ロール」の原則をどう守っているかをメモしておきましょう。

一行まとめ: IAM はユーザー · グループ · ロール · ポリシーの4要素から成り、ポリシーがすなわち権限。ポリシーは Effect + Action + Resource (+ Condition)の JSON で、Deny が Allow に勝つ。人はグループで束ね、マシンはロールで認証情報を受け取り、コードにキーを入れないのが事故を防ぐ基本。

次の章 #

IAM ユーザーができたので、次は決済の番です。最初の数日間で最も大きな事故は、眠っているリソースが請求書を膨らませることです。次の 第3章 コスト管理 では、登録直後に必ずオンにすべき決済アラートと無料利用枠の限度モニタリング、そして運用段階の Cost Explorer とタグ戦略までを整理します。

X