AWS基礎 #2 IAM — ユーザー、グループ、ロール、ポリシー

読了 11分

#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権限ルールの配列
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 が 1 つでもあれば → 拒否 (終了)
2) 明示的な Allow が 1 つでもあれば → 許可
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)
権限グループに追加、ポリシーを直接アタッチ、または別ユーザーからコピー

ベストプラクティス: ユーザーにポリシーを直接付けません。グループを通して 付けます。理由は次節で説明します。

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

アクセスキーは 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 に pushOIDC で GitHub Actions Workflow
一時的な権限昇格 (Break-glass)ユーザーが明示的に

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

ロールの 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)入門 / 標準的な場面
カスタマー管理自分で作るポリシー。複数のユーザー / ロールで再利用可能運用標準 — 推奨
インライン1 つのユーザー / グループ / ロールにだけ直接埋め込んだもの非推奨 — 再利用不可、追跡困難

よく使う AWS マネージドポリシー #

名前何か
AdministratorAccessすべての権限。ルートの次に危険
PowerUserAccessIAM 以外のほぼすべての権限
ReadOnlyAccessすべてのサービスの読み取りのみ
Billing請求コンソール
<Service>FullAccess (例: AmazonS3FullAccess)1 つのサービスの全権
<Service>ReadOnlyAccess1 つのサービスの読み取り

最初はマネージドで始め → 徐々に絞り込んで カスタマー管理に移すのが一般的な流れ。

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

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

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

単位名前何か
グループAdminsAdministratorAccess (MFA 強制)
グループDevelopersPowerUserAccess + IAM 拒否
グループReadOnlyReadOnlyAccess
グループBilling請求 / コスト
ロールEC2-AppRoleアプリが使う場面 (S3、RDS など)
ロールLambda-WorkerRoleLambda 用
ロール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 行で環境分離ができます。

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 / タグ戦略まで整理します。

X