AWS IAMは、AWS運用の安全性を決める中核サービスです。
EC2、S3、Lambda、RDS、CloudWatchなど、AWS上のほぼすべての操作は「誰が」「何に対して」「どの操作を許可されているか」によって制御されます。この判定を担うのがIAMです。
一方で、IAMは最初につまずきやすい領域でもあります。
- IAMユーザーとIAMロールの違いが曖昧
- ポリシーJSONの
ActionとResourceの書き方がわからない AdministratorAccessを付けたまま本番運用している- EC2やLambdaにアクセスキーを置いてしまう
- 最小権限にしたいが、どこまで削ればよいかわからない
IAMは「なんとなく動く権限」を付けるだけなら簡単です。しかし、本番環境で安全に運用するには、ポリシー・ロール・最小権限の原則を正しく理解する必要があります。
この記事では、AWS IAMの基本概念から、実務で使えるポリシー設計、IAMロールの使い方、最小権限への落とし込み方までを体系的に解説します。
この記事でわかること
- AWS IAMの役割と基本構成
- IAMユーザー・グループ・ロール・ポリシーの違い
- IAMポリシーJSONの読み方と書き方
- IAMロールを使うべき場面
- 最小権限の原則を実務で適用する手順
- IAM設計でよくある危険なパターン
前提条件: AWSアカウントを作成済みで、EC2・S3・CloudWatchなどの基本サービス名を知っていることを前提にします。運用監視の文脈は、CloudWatch入門|SREが最初に設定すべき5つの機能と優先順位 や AWSの本番環境で障害が起きたときの初動対応チェックリスト とあわせて読むと理解しやすくなります。

AWS IAMとは
AWS IAM(Identity and Access Management)は、AWSリソースへのアクセスを安全に制御するためのサービスです。
IAMで管理するのは、大きく分けると次の2つです。
| 観点 | 説明 |
|---|---|
| 認証 | 誰であるかを確認する |
| 認可 | 何を実行してよいかを判断する |
ログインやAPIアクセスで「この人・このシステムは誰か」を確認するのが認証です。そのうえで「S3バケットを読み取ってよいか」「EC2を停止してよいか」「IAMポリシーを変更してよいか」を判断するのが認可です。
IAMを理解するうえで重要なのは、AWSの操作がすべてAPIとして評価される点です。
たとえばAWSマネジメントコンソールでEC2インスタンス一覧を開く操作も、裏側では ec2:DescribeInstances のようなAPI権限で判定されます。AWS CLIでS3にファイルをアップロードする操作も、s3:PutObject の権限で判定されます。
つまりIAMは、コンソール利用者だけでなく、CLI、SDK、Lambda、EC2、ECS、EKS、CI/CD、外部監視ツールなど、AWSにアクセスするすべての主体に関係します。
IAMはグローバルサービス
IAMはリージョン単位ではなく、AWSアカウント全体に効くグローバルサービスです。
東京リージョンのEC2を操作する権限も、バージニア北部リージョンのS3を操作する権限も、同じIAMで管理します。したがって、IAMの設定ミスは1リージョンだけでなく、アカウント全体のリスクになります。
本番環境では「IAMは共通基盤であり、変更影響が広い」という前提で扱う必要があります。
IAMの基本要素
IAMでは、複数の要素を組み合わせてアクセス制御を行います。最初に押さえるべき要素は次の4つです。
| 要素 | 役割 | 主な用途 |
|---|---|---|
| IAMユーザー | 長期的な認証情報を持つ個別ID | 例外的な人間アクセス、レガシー用途 |
| IAMグループ | IAMユーザーをまとめる単位 | 複数ユーザーへの権限付与 |
| IAMロール | 一時的に引き受ける権限 | AWSサービス、外部ID連携、クロスアカウント |
| IAMポリシー | 許可・拒否のルール | 具体的な操作権限の定義 |
IAMユーザー
IAMユーザーは、AWSアカウント内に作成する個別のIDです。
以前は「人間の利用者ごとにIAMユーザーを作る」構成が一般的でした。しかし現在の実務では、人間のログインにはIAM Identity Centerや外部IdPとのフェデレーションを使い、IAMユーザーの常用を避ける設計が推奨されます。
IAMユーザーは長期的なアクセスキーを持てるため、漏えい時の影響が大きくなります。特に次の使い方は避けるべきです。
- 個人PCにIAMユーザーのアクセスキーを長期間保存する
- 退職者・異動者のIAMユーザーを放置する
- 複数人で同じIAMユーザーを共有する
- 本番運用で
AdministratorAccessを付けたIAMユーザーを常用する
人間のアクセスは、可能な限りIAM Identity CenterやSSOに寄せます。IAMユーザーは、どうしても必要な互換性用途に限定します。
IAMグループ
IAMグループは、IAMユーザーをまとめて権限を付与するための仕組みです。
たとえば Developers グループに開発環境の操作権限を付け、ReadOnly グループに参照権限を付けるような使い方です。
ただし、IAMグループはIAMユーザーを前提にした仕組みです。人間アクセスをIAM Identity Centerへ移行している環境では、IAMグループよりもIdentity Center側のグループと許可セットで管理するほうが自然です。
IAMロール
IAMロールは、特定の主体が一時的に引き受ける権限です。
IAMロールは、AWS運用で最も重要な要素の1つです。理由は、長期的なアクセスキーを使わずに権限を渡せるからです。
代表的な利用例は次のとおりです。
- EC2からS3へアクセスするためにインスタンスプロファイルを使う
- Lambda関数にDynamoDB読み書き権限を付ける
- ECSタスクからSecrets Managerを参照する
- GitHub ActionsからOIDCでAWSロールを引き受ける
- 別AWSアカウントの監査ロールを引き受ける
アプリケーションや運用自動化からAWSへアクセスする場合、原則としてIAMユーザーのアクセスキーではなくIAMロールを使います。
IAMポリシー
IAMポリシーは、どの操作を許可または拒否するかをJSONで定義するルールです。
IAMポリシーには複数の種類があります。
| 種類 | 説明 |
|---|---|
| AWS管理ポリシー | AWSが用意する管理ポリシー |
| カスタマー管理ポリシー | 自分のアカウントで作成・管理する再利用可能なポリシー |
| インラインポリシー | 特定のユーザー・ロール・グループに直接埋め込むポリシー |
| リソースベースポリシー | S3バケットやKMSキーなどリソース側に付けるポリシー |
| 信頼ポリシー | IAMロールを誰が引き受けられるかを定義するポリシー |
実務では、再利用したい権限はカスタマー管理ポリシー、特定ロール専用の権限はインラインポリシー、S3やKMSなどリソース側の制御が必要な場合はリソースベースポリシーを使います。
IAMポリシーの読み方
IAMポリシーはJSONで書きます。最小構成は次のようになります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-bucket/*"
}
]
}
このポリシーは、example-bucket 内のオブジェクトを読み取る s3:GetObject を許可します。
IAMポリシーで特に重要なのは、次の4項目です。
| 項目 | 意味 |
|---|---|
| Effect | Allow または Deny |
| Action | 許可・拒否するAPI操作 |
| Resource | 対象リソースのARN |
| Condition | 条件付き制御 |
Effect
Effect は、そのステートメントが許可なのか拒否なのかを示します。
"Effect": "Allow"
または次のように明示的な拒否を書きます。
"Effect": "Deny"
IAMでは、明示的なDenyがAllowより優先されます。つまり、あるポリシーで許可されていても、別のポリシーで明示的に拒否されていれば操作できません。
この仕組みは、組織全体で危険な操作を止める場合に有効です。たとえば本番アカウントで特定リージョン以外の操作を拒否する、MFAなしの重要操作を拒否する、といった設計ができます。
Action
Action は、許可・拒否するAPI操作です。
"Action": [
"ec2:DescribeInstances",
"ec2:DescribeInstanceStatus"
]
ec2:* のようなワイルドカードも使えますが、本番環境では広すぎる権限になりがちです。最初は広めに付けたとしても、CloudTrailやAccess Analyzerの情報を使って実際に必要な操作へ絞り込む必要があります。
Resource
Resource は、操作対象のリソースをARNで指定します。
"Resource": "arn:aws:s3:::example-bucket/*"
S3、KMS、SQS、SNS、DynamoDBなどは、比較的細かくリソースを指定できます。一方で、AWSサービスやAPIによっては Resource に個別ARNを指定できず、"*" が必要なものもあります。
重要なのは、Resource: "*" を見つけたときにすぐ悪と決めつけるのではなく、「そのActionはリソースレベル権限に対応しているか」を確認することです。対応しているならARNで絞り、対応していないならConditionで補います。
Condition
Condition は、条件付きで許可・拒否を制御する項目です。
たとえば、特定リージョンでのみ操作を許可する例です。
{
"Effect": "Allow",
"Action": "ec2:*",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:RequestedRegion": "ap-northeast-1"
}
}
}
Conditionを使うと、IPアドレス、MFA有無、リクエストリージョン、タグ、Principal ARNなどで制御できます。
最小権限を実現するには、ActionとResourceだけでなく、Conditionも設計対象に含めます。

IAMの権限評価ロジック
IAMで混乱しやすいのが、複数のポリシーが同時に関係する場合の評価です。
たとえば、あるIAMロールに次の設定があるとします。
- identity-based policyでS3読み取りを許可
- S3バケットポリシーで特定Principalのみ許可
- AWS OrganizationsのSCPで一部操作を拒否
- permission boundaryで許可上限を制限
このとき、最終的に操作できるかどうかは、複数のポリシーを組み合わせて評価されます。
基本原則は次の3つです。
- デフォルトは拒否
- 明示的なAllowがあれば許可候補になる
- 明示的なDenyがあれば最終的に拒否
IAMでは、何も許可されていない操作は拒否されます。これを暗黙的なDenyと考えます。
そこにAllowポリシーが付くと、操作が許可される可能性が出ます。ただし、どこかに明示的なDenyがあると、Allowがあっても拒否されます。
明示的Denyを使う場面
明示的Denyは強力です。使いすぎるとトラブルシューティングが難しくなりますが、組織の安全柵としては有効です。
よくある利用例は次のとおりです。
- rootユーザー以外でも請求関連の一部操作を禁止する
- 承認されたリージョン以外でのリソース作成を禁止する
- MFAなしで重要操作を実行できないようにする
- 特定タグがないリソース作成を禁止する
- 本番環境の削除操作を一部ロール以外に禁止する
SREの観点では、明示的Denyは「事故が起きたときに個人の注意力に依存しない安全柵」として設計します。
IAMロールを使うべき場面
IAMロールは、AWSの実務運用で最優先に理解すべき概念です。
ロールは「権限の束」ではありますが、単なるポリシーの入れ物ではありません。ロールには次の2つの側面があります。
| 要素 | 説明 |
|---|---|
| 信頼ポリシー | 誰がこのロールを引き受けられるか |
| 権限ポリシー | 引き受けた後に何ができるか |
この2つを分けて理解することが重要です。
信頼ポリシー
信頼ポリシーは、IAMロールを誰が引き受けられるかを定義します。
たとえば、EC2がロールを引き受けるための信頼ポリシーは次のような形です。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
このポリシーは「EC2サービスがこのロールを引き受けられる」ことを示します。
一方で、ロールを引き受けた後にS3を読めるか、CloudWatch Logsへ書けるか、DynamoDBへアクセスできるかは、権限ポリシーで決まります。
EC2からS3へアクセスする例
EC2上のアプリケーションからS3を読む場合、アクセスキーをEC2内に置くのではなく、IAMロールをインスタンスプロファイルとして関連付けます。
権限ポリシーは次のようにします。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::example-app-config",
"arn:aws:s3:::example-app-config/*"
]
}
]
}
この設計なら、EC2に長期アクセスキーを保存する必要がありません。認証情報はAWS側で一時的に発行・ローテーションされます。
Lambdaの実行ロール
Lambda関数にもIAMロールを関連付けます。これを実行ロールと呼びます。
たとえば、LambdaからDynamoDBの特定テーブルを読み書きする場合は、次のように対象テーブルを絞ります。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/orders"
}
]
}
ここで dynamodb:* や Resource: "*" を使うと、Lambdaの不具合や侵害時の影響範囲が広がります。関数単位で必要な操作と対象リソースを絞ることが重要です。
最小権限の原則とは
最小権限の原則とは、利用者やシステムに対して、業務・処理に必要な最小限の権限だけを付与する考え方です。
AWS IAMでは、次の4つを最小化します。
| 対象 | 最小化する内容 |
|---|---|
| Principal | 誰が操作できるか |
| Action | どのAPI操作ができるか |
| Resource | どのリソースに対して操作できるか |
| Condition | どの条件で操作できるか |
最小権限は、最初から完璧に作るものではありません。実務では、次のサイクルで継続的に近づけます。
- 最初は用途別のロールを分ける
- AWS管理ポリシーや広めの権限で検証する
- CloudTrailで実際に使われたAPIを確認する
- Access Analyzerでポリシーを生成・検証する
- 未使用権限を削る
- 本番では変更レビューを通す
「最小権限」は一度作って終わりではなく、運用しながら削り続ける設計です。
最初から細かくしすぎない
最小権限を意識しすぎるあまり、初期構築段階で権限を細かくしすぎると、開発速度が落ちることがあります。
重要なのは、環境ごとに段階を分けることです。
| 環境 | 権限設計の考え方 |
|---|---|
| 検証環境 | やや広めでもよいが、個人の管理者権限常用は避ける |
| ステージング | 本番に近いロール構成で動作確認する |
| 本番環境 | Action・Resource・Conditionを絞る |
本番環境では「便利だからAdmin」ではなく、「必要な操作だけを明示的に許可する」方針に切り替えます。

最小権限を実装する手順
ここからは、IAMを最小権限へ近づける実務手順を解説します。
Step 1: 人間とシステムのアクセスを分ける
最初に、人間が使う権限とシステムが使う権限を分けます。
人間向けには、IAM Identity Centerや外部IdP連携を使い、職務ごとの許可セットを設計します。
例:
- ReadOnly
- Developer
- SREOperator
- SecurityAuditor
- BillingAdmin
システム向けには、EC2、Lambda、ECS、EKS、CI/CDなど用途ごとにIAMロールを作ります。
例:
app-frontend-ec2-roleapp-worker-lambda-rolegithub-actions-deploy-rolemonitoring-readonly-role
人間とシステムの権限を混ぜると、監査・棚卸し・削除が難しくなります。まず分離することが重要です。
Step 2: 管理者権限を日常利用しない
AWS管理ポリシーの AdministratorAccess は強力です。初期構築時には便利ですが、日常運用で常用すべきではありません。
本番環境では、管理者権限を次のように扱います。
- 通常作業は職務別ロールで行う
- 管理者権限は緊急時・基盤変更時だけ使う
- 管理者権限の利用はCloudTrailで監査する
- MFAや承認フローを必須にする
- 使った後に理由と作業内容を記録する
管理者権限をゼロにする必要はありません。問題は「誰でも、いつでも、理由なく使える状態」です。
Step 3: サービスごとにロールを分ける
1つの巨大なIAMロールを複数サービスで共有すると、最小権限にできません。
たとえば、次のようなロールは避けます。
app-all-purpose-role
このロールにS3、DynamoDB、SQS、CloudWatch、Secrets Manager、KMSなどの権限をまとめて付けると、どのサービスがどの権限を必要としているか見えなくなります。
代わりに、用途ごとにロールを分けます。
frontend-ec2-role
order-worker-lambda-role
batch-job-ecs-task-role
deploy-github-actions-role
ロールを分けることで、CloudTrailやAccess Analyzerで利用実績を確認しやすくなり、不要権限も削りやすくなります。
Step 4: CloudTrailで実利用APIを確認する
IAMポリシーを最小化するには、実際に使われているAPIを知る必要があります。
CloudTrailでは、AWSアカウント内のAPIイベントを記録できます。たとえば、特定ロールが過去に実行したAPIをCloudTrail Lakeやログ検索で確認し、使われていない権限を削る判断材料にできます。
AWS CLIでCloudTrailイベントを確認する例です。
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=Username,AttributeValue=app-worker-lambda-role \
--max-results 20
実際の環境では、AssumedRoleのセッション名やPrincipal ARNを見ながら対象を絞ります。CloudTrailのログはIAM改善だけでなく、インシデント調査にも使えるため、必ず有効化しておきます。
Step 5: Access Analyzerでポリシーを検証する
IAM Access Analyzerは、ポリシーの検証や外部アクセスの検出に使えるサービスです。
実務では次の用途で役立ちます。
- ポリシーJSONの警告やエラーを検出する
- 外部アカウントからアクセス可能なリソースを検出する
- CloudTrailの利用実績からポリシー生成を支援する
- 未使用アクセスを見つける
ポリシーを作ったら、手作業レビューだけでなくAccess Analyzerで検証します。
aws accessanalyzer validate-policy \
--policy-document file://policy.json \
--policy-type IDENTITY_POLICY
このコマンドにより、ポリシーの構文やベストプラクティス上の問題を検出できます。CI/CDに組み込めば、危険なIAMポリシーをレビュー前に検出できます。
Step 6: タグとConditionで運用境界を作る
本番環境では、タグベースの制御も有効です。
たとえば、Environment=production のリソース削除を一部ロール以外に拒否する、Project タグが一致するリソースだけ操作を許可する、といった設計ができます。
ただし、タグベース制御はタグの付け忘れや変更権限とセットで考える必要があります。
タグで権限を制御する場合は、次の点も設計します。
- 必須タグを作成時に強制する
- タグを変更できるロールを限定する
- タグ変更もCloudTrailで監査する
- IaCでタグを標準化する
タグは便利ですが、タグ自体を誰でも変更できると権限境界として弱くなります。
IAM設計でよくある危険なパターン
IAMの事故は、複雑な攻撃よりも、日常的な設定ミスから起きることが多いです。
危険1: アクセスキーをコードやサーバーに置く
もっとも避けたいのが、アクセスキーをソースコード、.env、EC2内、CI/CDの平文変数に置くことです。
アクセスキーが漏えいすると、そのキーに付いている権限でAWS APIを実行される可能性があります。
対策は次のとおりです。
- AWSサービスからのアクセスはIAMロールを使う
- GitHub Actionsなど外部CI/CDはOIDCでロールを引き受ける
- どうしてもアクセスキーが必要な場合は権限を限定し、定期ローテーションする
- secret scanningを有効化する
危険2: Action: "*" と Resource: "*" を放置する
検証段階で広い権限を使うことはあります。しかし、それを本番に残すとリスクになります。
特に次のようなポリシーは危険です。
{
"Effect": "Allow",
"Action": "*",
"Resource": "*"
}
これは実質的に管理者権限です。どの操作が必要なのか判断できない場合でも、まずサービス単位に絞ります。
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-app-bucket",
"arn:aws:s3:::example-app-bucket/*"
]
}
その後、利用実績を見て s3:GetObject、s3:PutObject、s3:ListBucket のように絞ります。
危険3: rootユーザーを日常利用する
AWSアカウントのrootユーザーは、アカウント作成時のメールアドレスで作られる最上位のユーザーです。
rootユーザーは通常作業に使うべきではありません。rootユーザーでしかできない一部操作を除き、日常運用はIAM Identity CenterやIAMロールで行います。
rootユーザーには、少なくとも次の対策を行います。
- MFAを有効化する
- アクセスキーを作成しない
- 利用できる人を極小化する
- 利用時は記録を残す
危険4: ロールの信頼ポリシーが広すぎる
権限ポリシーだけでなく、信頼ポリシーも重要です。
たとえばクロスアカウントロールで、信頼先を広くしすぎると、意図しない主体がロールを引き受けられる可能性があります。
信頼ポリシーでは、Principalを具体的に絞り、必要に応じてExternal ID、組織ID、条件キーを使います。
危険5: 権限を削る責任者がいない
IAMは作成時よりも、運用後に権限が増え続けることが問題になりがちです。
障害対応やリリース作業で一時的に付けた権限が、そのまま残ることがあります。これを防ぐには、IAM権限の棚卸しを定期運用に組み込みます。
たとえば、月1回または四半期に1回、次の観点でレビューします。
- 長期間使われていないIAMユーザーはないか
- 未使用のアクセスキーはないか
- 管理者権限を持つPrincipalは多すぎないか
- 外部公開されたリソースポリシーはないか
- 一時的に付けた権限が残っていないか
実務で使えるIAM設計チェックリスト
IAM設計をレビューするときは、次のチェックリストを使います。
アカウントと人間アクセス
- [ ] rootユーザーにMFAを設定している
- [ ] rootユーザーのアクセスキーを作成していない
- [ ] 人間のログインにIAM Identity Centerまたはフェデレーションを使っている
- [ ] 共有IAMユーザーを使っていない
- [ ] 管理者権限の利用者と利用目的を把握している
システムアクセス
- [ ] EC2、Lambda、ECS、EKS、CI/CDにIAMロールを使っている
- [ ] アクセスキーをコードやサーバー内に保存していない
- [ ] サービス・用途ごとにロールを分けている
- [ ] ロール名から用途がわかる
- [ ] 不要になったロールを削除している
ポリシー設計
- [ ]
Action: "*"を本番で放置していない - [ ]
Resource: "*"が必要な理由を説明できる - [ ] 可能なリソースはARNで絞っている
- [ ] Conditionでリージョン・MFA・タグなどを制御している
- [ ] 明示的Denyの用途と影響範囲を説明できる
運用と監査
- [ ] CloudTrailを有効化している
- [ ] Access Analyzerでポリシーを検証している
- [ ] 未使用権限を定期的に確認している
- [ ] IAM変更をレビュー対象にしている
- [ ] 緊急時の権限昇格手順をRunbook化している
IAMは一度設定して終わりではありません。新しいサービス、チーム変更、デプロイ方式の変更に合わせて、継続的に見直す必要があります。
まとめ
AWS IAMは、AWSセキュリティの基礎であり、本番運用の土台です。
この記事のポイントは次のとおりです。
- IAMはAWSリソースへの認証・認可を制御するサービス
- 人間のアクセスはIAM Identity Centerやフェデレーションを優先する
- AWSサービスやCI/CDからのアクセスはIAMロールを使う
- IAMポリシーは
Effect、Action、Resource、Conditionで読む - 明示的DenyはAllowより優先される
- 最小権限はCloudTrailやAccess Analyzerを使って継続的に近づける
- 管理者権限・アクセスキー・広すぎる信頼ポリシーは重点的に管理する
IAMを理解すると、AWS運用の見え方が大きく変わります。単に「権限エラーを直す」だけでなく、障害時の影響範囲、運用自動化の安全性、監査対応、インシデント調査まで設計できるようになります。
AWS運用を実務レベルで学びたい場合は、CloudWatchの監視設計やSLO、インシデント対応を体系的に扱う以下の講座も参考になります。
AWS×SRE入門〜CloudWatchで学ぶ監視設計の基礎〜
IAMはすべてのAWS運用の入口です。まずは、管理者権限の常用をやめ、ロールを用途ごとに分け、CloudTrailとAccess Analyzerで実利用に合わせて権限を削るところから始めるのが現実的です。

コメント