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 | 権限ルールの配列 |
Effect | Allow または Deny |
Action | どの API 呼び出しを許可 / 拒否するか — <サービス>:<アクション> |
Resource | どのリソースに — ARN で |
Condition (オプション) | 追加条件 — IP、時間、タグなど |
Action の形式 #
s3:GetObject のように <サービス>:<アクション> の形式です。ワイルドカードも使えます。
"Action": "s3:Get*" // s3 のすべての Get アクション
"Action": "s3:*" // s3 のすべてのアクション
"Action": ["s3:GetObject", "s3:PutObject"] // 配列で複数Resource の形式 #
ARN で書きます。ARN の形は 第1章 で見ました。
"Resource": "arn:aws:s3:::my-bucket" // バケット自体
"Resource": "arn:aws:s3:::my-bucket/*" // バケット内のすべてのオブジェクト
"Resource": "arn:aws:s3:::my-bucket/uploads/*" // 特定の prefix だけ
"Resource": "*" // すべてのリソース (危険)Condition — 最も強力な制御手段 #
条件がポリシーの本当の力を作る部分です。
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "arn:aws:s3:::my-bucket/*",
"Condition": {
"IpAddress": {
"aws:SourceIp": ["203.0.113.0/24"]
}
}
}{
"Effect": "Allow",
"Action": "iam:*",
"Resource": "*",
"Condition": {
"Bool": { "aws:MultiFactorAuthPresent": "true" }
}
}よく使う条件キーは次のとおりです。
| キー | 何か |
|---|---|
aws:SourceIp | リクエスト IP |
aws:MultiFactorAuthPresent | MFA の使用有無 |
aws:RequestTag/<key> | 作るときのタグ |
aws:ResourceTag/<key> | リソースのタグ |
aws:CurrentTime | 時間 |
Allow / Deny の評価順序 #
複数のポリシーが重なると、IAM は次の順序で決定します。
1) 明示的な Deny が一つでもあれば → 拒否 (終了)
2) 明示的な Allow が一つでもあれば → 許可
3) どちらもなければ → 拒否 (デフォルト)Deny が常に勝ちます。 そのため「このユーザーは prod リソースだけは絶対に触れないように」のようなガードレールは Deny で書きます。許可ポリシーの隣に Deny を付けるパターンです。
User — 人 / マシンのための永続的な認証情報 #
IAM ユーザーはメールアドレスではなく別途の ID です。コンソールログイン URL も別に生成されます。
https://<アカウントID>.signin.aws.amazon.com/console
または
https://<アカウントエイリアス>.signin.aws.amazon.com/consoleユーザーを作る #
コンソールで IAM → Users → Add users へ入ります。
| 項目 | 何か |
|---|---|
| ユーザー名 | メールアドレスではありません。curtis、dev-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 に push | OIDC で GitHub Actions |
| 一時的な権限昇格 (Break-glass) | ユーザーが明示的に |
EC2 / Lambda / ECS のような環境では、AWS が自動的に AssumeRole をして認証情報をインスタンスに流してくれます。コードはただ SDK を呼べばよいだけです。アクセスキーを扱う必要がありません。これが核心です。
ロールの2つのポリシー #
ロールには2種類のポリシーが付きます。
1) Trust Policy (信頼ポリシー) — 誰がこのロールを借りられるかを定めます。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "ec2.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}Principal 項目に誰が入ります — サービス、他のアカウント、ユーザー、OIDC provider などです。
2) Permission Policy (権限ポリシー) — 借りた後に何ができるかを定めます。
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}EC2 インスタンスプロファイルの流れ #
[EC2 インスタンス]
│
│ 1) インスタンスメタデータ (169.254.169.254)に認証情報を要求
▼
[IAM]
│ 2) インスタンスに付いたロールの一時認証情報を発行
▼
[EC2 の中の SDK]
│ 3) 認証情報で S3 を呼び出し
▼
[S3]EC2 の中のコードはアクセスキーを知りません。boto3 や aws-sdk が自動でメタデータから認証情報を取り出して使います。キー漏洩の事故を根本的に減らしてくれます。
管理ポリシー vs インラインポリシー #
ポリシーは作り方でさらに分かれます。
| 種類 | 何か | 推奨 |
|---|---|---|
| AWS 管理 | AWS が作っておいたもの (例: AdministratorAccess、ReadOnlyAccess) | 入門 / 標準ロール |
| カスタマー管理 | 自分が作ったポリシー。複数のユーザー / ロールに再利用可能 | 運用標準 — 推奨 |
| インライン | 一つのユーザー / グループ / ロールにだけ直接付与したもの | 非推奨 — 再利用できない、追跡が難しい |
よく使う AWS 管理ポリシー #
| 名前 | 何か |
|---|---|
AdministratorAccess | すべての権限。ルートの次に危険 |
PowerUserAccess | IAM を除くほぼすべての権限 |
ReadOnlyAccess | すべてのサービスの読み取りだけ |
Billing | 決済コンソール |
<Service>FullAccess (例: AmazonS3FullAccess) | 一つのサービスの全部 |
<Service>ReadOnlyAccess | 一つのサービスの読み取り |
最初は管理ポリシーで始めて、徐々に絞ってカスタマー管理へ移すのが一般的な流れです。
運用の権限設計 — 通用するパターン #
小さなチームでも通用する権限設計の骨格です。
1) グループ4 + ロール3 #
| 単位 | 名前 | 何か |
|---|---|---|
| グループ | Admins | AdministratorAccess (MFA 強制) |
| グループ | Developers | PowerUserAccess + IAM 拒否 |
| グループ | ReadOnly | ReadOnlyAccess |
| グループ | Billing | 決済 / コスト |
| ロール | EC2-AppRole | アプリが使うロール (S3、RDS など) |
| ロール | Lambda-WorkerRole | ラムダ用 |
| ロール | CICDRole | GitHub Actions / CodeBuild が借りる |
2) 権限境界 (Permission Boundary) #
「この IAM ユーザーは何をしてもこの限度の中だけで」を定める保護膜です。新人開発者が新しいポリシーを作って自分の権限を増やす事故を遮断します。
Developers グループ → PowerUserAccess
↓ そしてすべてのユーザーに権限境界を付与
権限境界 → "DevOnly" — dev/* リソースだけ作れる3) MFA 強制 #
ルートとすべての IAM ユーザーに強制します。強制ポリシーの形は 第6章 セキュリティ基本 で詳しく扱います。
4) ユーザー ↔ ロールの分離 #
ユーザーは人だけ、マシンはすべてロールにします。これが明確であればアクセスキーの事故はほとんど起こりません。
5) 条件でガードレール #
{
"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 だけ、アクセスキーは絶対に作りません。
練習問題 #
- §「Allow / Deny の評価順序」を根拠に、あるユーザーに
AdministratorAccessが付いているのに特定のバケットのオブジェクトを消せないようにするには、どの Statement を追加すべきかを JSON の断片で書いてみましょう。 - §「ロールの2つのポリシー」で Trust Policy と Permission Policy がそれぞれ何を決定するかを一文ずつ書き、第4章 CLI と SDK の
role_arn+source_profileプロファイルがこのうちどちらの流れを CLI で再現するかを結びつけてみましょう。 - 自分が運用する小さなチームを想定して §「グループ4 + ロール3」の表を自分の環境に合わせて書き直してみましょう。そのうちマシン用のロールを一つ選び、そのロールが 第6章 セキュリティ基本 の「ユーザー = 人、マシン = ロール」の原則をどう守っているかをメモしておきましょう。
一行まとめ: IAM はユーザー · グループ · ロール · ポリシーの4要素から成り、ポリシーがすなわち権限。ポリシーは
Effect+Action+Resource(+Condition)の JSON で、Deny が Allow に勝つ。人はグループで束ね、マシンはロールで認証情報を受け取り、コードにキーを入れないのが事故を防ぐ基本。
次の章 #
IAM ユーザーができたので、次は決済の番です。最初の数日間で最も大きな事故は、眠っているリソースが請求書を膨らませることです。次の 第3章 コスト管理 では、登録直後に必ずオンにすべき決済アラートと無料利用枠の限度モニタリング、そして運用段階の Cost Explorer とタグ戦略までを整理します。