AWS基礎 #2 IAM — ユーザー、グループ、ロール、ポリシー
#1 AWS入門 の最後で「ルートユーザーで作業しないこと」を話しました。では誰として作業するのか。答えは IAM (Identity and Access Management) で作るユーザー / ロールです。
IAM はグローバルサービス — どのリージョンでコンソールを開いても同じユーザー / ロール / ポリシーが見えます。そして 無料。追加コストなしで無制限にユーザーを作れます。だから AWS に入って最初に出会うべきサービスです。
この記事では IAM の 4 つの要素 を 1 本の糸で通し、運用での権限設計の核となるパターンまで整理します。
全体像 — IAM の 4 つの要素 #
| 要素 | 何か | 誰が / 何が使うか |
|---|---|---|
| User (ユーザー) | 人 1 人またはマシン 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 が 1 つでもあれば → 拒否 (終了)
2) 明示的な Allow が 1 つでもあれば → 許可
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) |
| 権限 | グループに追加、ポリシーを直接アタッチ、または別ユーザーからコピー |
ベストプラクティス: ユーザーにポリシーを直接付けません。グループを通して 付けます。理由は次節で説明します。
アクセスキー — ユーザーが持つもっとも危険な認証情報 #
アクセスキーは 2 行の文字列です。
Access Key ID: AKIAIOSFODNN7EXAMPLE
Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEYこれら 2 つを持つ誰もが そのユーザーのすべての権限 を行使できます。だから:
- ユーザー 1 人につきアクセスキーは最大 2 個 (ローテーション中だけ 2 つが共存)
- 絶対に git / コードに入れない (#1 落とし穴 #2 の事例)
- 90 日ごとにローテーション (#6 で詳しく)
- 可能ならユーザーアクセスキーの代わりに ロール (Role) を使う
Group — ユーザー管理の単位 #
グループはユーザーを束ねる単位です。グループにポリシーを付ければそのグループの全ユーザーに自動で適用されます。
Admins → AdministratorAccess
Developers → PowerUserAccess + (IAM 拒否ポリシー)
ReadOnly → ReadOnlyAccess
Billing → 請求コンソールアクセスのみなぜユーザーに直接ではなくグループに? #
新しい開発者が入社した場面を想像してみましょう。
ユーザー直接モデル:
- 既存の開発者を 1 人選んでポリシーリストを真似る
- 「あれ、あの人に 1 週間前に追加したポリシーは何だっけ?」 → 漏れ
- 時間が経つと開発者ごとに権限が微妙に違ってくる
グループモデル:
Developersグループに追加するだけで終わり- 権限変更はグループのポリシーを変えるだけで全員に一貫適用
- 監査 / 点検もグループ単位できれいです
ルール: IAM ユーザーには インラインポリシー / 直接アタッチポリシー禁止。すべての権限はグループまたはロールで。
Role — 「一時的に借りて使う」認証情報 #
Role は 誰かの認証情報ではなく、何でも一時的に借りて使える認証情報 です。永続的なパスワード / アクセスキーがありません。代わりに誰か / 何かが AssumeRole という呼び出しをすると、AWS が一時的な認証情報 (1 時間 ~ 12 時間有効) を発行してくれます。
これが IAM のもっとも重要なところです。最初は難しいですが、慣れると IAM の本当の力が見えてきます。
ロールが効く場面 #
| シナリオ | 誰が AssumeRole するか |
|---|---|
| EC2 が S3 にアクセス | EC2 インスタンス (自動で) |
| Lambda が DynamoDB に書き込み | Lambda (自動で) |
| ECS Task が他のサービスを呼び出し | Task (自動で) |
| 別の AWS アカウントのユーザーがこのアカウントの一部のリソースにアクセス | そのユーザーが明示的に |
| GitHub Actions が ECR に push | OIDC で GitHub Actions Workflow |
| 一時的な権限昇格 (Break-glass) | ユーザーが明示的に |
EC2 / Lambda / ECS のような場面では AWS が自動で AssumeRole をして認証情報をインスタンスに流してくれます。コードはただ SDK を呼べば OK — アクセスキーを扱う必要がありません。これが核心です。
ロールの 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) | 入門 / 標準的な場面 |
| カスタマー管理 | 自分で作るポリシー。複数のユーザー / ロールで再利用可能 | 運用標準 — 推奨 |
| インライン | 1 つのユーザー / グループ / ロールにだけ直接埋め込んだもの | 非推奨 — 再利用不可、追跡困難 |
よく使う AWS マネージドポリシー #
| 名前 | 何か |
|---|---|
AdministratorAccess | すべての権限。ルートの次に危険 |
PowerUserAccess | IAM 以外のほぼすべての権限 |
ReadOnlyAccess | すべてのサービスの読み取りのみ |
Billing | 請求コンソール |
<Service>FullAccess (例: AmazonS3FullAccess) | 1 つのサービスの全権 |
<Service>ReadOnlyAccess | 1 つのサービスの読み取り |
最初はマネージドで始め → 徐々に絞り込んで カスタマー管理に移すのが一般的な流れ。
運用権限設計 — 通用するパターン #
小さなチームでも通用する権限設計の骨格。
1) グループ 4 + ロール 3 #
| 単位 | 名前 | 何か |
|---|---|---|
| グループ | Admins | AdministratorAccess (MFA 強制) |
| グループ | Developers | PowerUserAccess + IAM 拒否 |
| グループ | ReadOnly | ReadOnlyAccess |
| グループ | Billing | 請求 / コスト |
| ロール | EC2-AppRole | アプリが使う場面 (S3、RDS など) |
| ロール | Lambda-WorkerRole | Lambda 用 |
| ロール | 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 行で環境分離ができます。
Policy Simulator — 検証ツール #
IAM Policy Simulator (policysim.aws.amazon.com) はユーザー / グループ / ロールに対して 「このアクションは可能か?」 をシミュレーションしてくれるツール。ポリシー変更後に意図通りになったか確認用。
1) ユーザーまたはロールを選択
2) シミュレートするアクションを選択 (例: s3:DeleteObject)
3) リソース ARN を入力 (オプション)
4) 「Run Simulation」 → Allowed / Denied と、どのポリシーが効いたか#6 の IAM Access Analyzer も合わせて点検に役立ちます。
IAM ユーザーを作る — 実習 #
ここまで来たら直接 IAM ユーザーを 1 人作っておきましょう。#4 CLI からはこのユーザー / ロールが必要になります。
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 セキュリティの基本 に進みます。
よく出会う落とし穴 #
1) ユーザーにポリシーを直接アタッチ #
10 人までは大丈夫に見えますが、30 人になると権限が微妙に違い始めます。本番侵入時に誰の権限がどこまでか把握できません。グループに集めてください。
2) Resource: "*" の乱用
#
最初は楽ですが侵入時の被害範囲が無限大になります。可能なすべてのロールで ARN で絞り込みます。
3) インラインポリシー #
一発で埋め込むときは速いですが、1 ヶ月後に誰が追加したポリシーか分からなくなります。再利用も不可。カスタマー管理ポリシーに — 名前が付きバージョンが管理されます。
4) アクセスキーを EC2 内に埋め込む #
EC2 → S3 の認証をアクセスキーで解決するコード。インスタンスプロファイル (ロール) に移すべきです。キーローテーションを忘れると事故が永遠に潜伏します。
5) 「テスト用に作ったユーザー」がそのまま #
退職した社員のアクセスキー、一度作って忘れたボットユーザー。30 日 / 90 日未使用 のユーザーは自動で無効化 / 削除するポリシーを作りましょう。IAM Credential Report で一目で確認可能。
6) ルートユーザーにアクセスキー #
#1 落とし穴 #2 — もっともありがちな事故。ルートはコンソール + MFA だけ、アクセスキーは絶対に作りません。
まとめ #
今回つかんだもの:
- IAM の 4 つの要素 — User (人 / マシンの永続認証)、Group (ユーザーの束)、Role (一時的に借りる認証)、Policy (JSON 権限文書)
- ポリシーの形 —
Effect+Action+Resource(+Condition)。Deny が Allow に勝ちます - ユーザーへのポリシー直接アタッチ禁止 → グループに集めます
- Role の 2 つのポリシー — Trust Policy (誰が借りられるか) + Permission Policy (借りた後何ができるか)
- EC2 / Lambda / ECS はインスタンスプロファイル / 実行ロール で認証情報を受け取ります — コードにキーを埋め込みません
- マネージド vs インライン — カスタマー管理が運用標準
- 権限設計パターン — グループ 4 + ロール 3、権限境界、MFA 強制、ユーザー ↔ ロール分離、タグ + Condition ガードレール
- 落とし穴 — ユーザー直接ポリシー、
Resource:*、インラインポリシー、EC2 内アクセスキー、眠るユーザー、ルートキー
次回 — コスト管理 #
IAM ユーザーができたので、いよいよ 請求 の番です。最初の数日でもっとも大きな事故は 眠っているリソースが請求書を膨らませること です。
#3 コスト管理 — 請求アラーム、Cost Explorer、無料利用枠 では登録直後に必ず ON にすべき請求アラームと無料利用枠の上限モニタリング、そして運用段階の Cost Explorer / タグ戦略まで整理します。