- 技術 💻
IAMポリシーの書き方|JSONの読み方と最小権限の作り方【例文つき】
IAMポリシーとは、AWSで「誰が・何の操作を・どのリソースに対して・どんな条件で」行えるかを、JSONで書いた許可のルールです。ユーザーやロールにポリシーを付けることで、使える操作を決めます。
書き方の基本はシンプルですが、実務では「許可したのに動かない」「拒否したつもりが通ってしまう」といったつまずきがよく起きます。原因の多くは、Resourceの書き方の間違いと、許可・拒否が決まる順番(評価ロジック)の誤解です。この記事では、JSONの読み方と評価の順番を整理したうえで、コピーして使える例文と、よくある間違いを紹介します。例文は、IAMポリシーのリンター(parliament)で検査しています。
IAMポリシーの早見表
| 要素 | 意味 | 例 |
|---|---|---|
Version |
ポリシーの文法のバージョン | "2012-10-17"(常にこれを書く) |
Statement |
ルールの一覧 | [ { ... }, { ... } ] |
Sid |
ルールの名前(任意) | "ReadMonthlyReports" |
Effect |
許可か拒否か | "Allow" / "Deny" |
Action |
操作 | "s3:GetObject"、"ec2:StartInstances" |
Resource |
対象のリソース(ARN) | "arn:aws:s3:::example-reports/*" |
Condition |
条件 | タグ、リージョン、MFAの有無、IPアドレスなど |
NotAction |
指定した操作「以外」 | Denyと組み合わせて使うことが多い |
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「IAMポリシーの書き方|JSONの読み方と最小権限の作り方【例文つき】」
JSONの読み方
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadMonthlyReports",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-reports/monthly/*"
}
]
}
日本語にすると、「example-reports バケットの monthly/ 以下のファイルを、読み取ることを許可する」という意味です。
Actionはサービス名:操作名の形で書きます。s3:Get*のようにワイルドカードも使えますResourceは ARN(Amazonリソースネーム)で書きますActionやResourceは、配列で複数指定できます
許可と拒否はどう決まるか:評価の順番
IAMでは、次のルールで最終的な結果が決まります。
| 順番 | ルール |
|---|---|
| 1 | 何も書かれていなければ、拒否(暗黙の拒否) |
| 2 | どこかに Allow があれば、許可の候補になる |
| 3 | どこか1か所にでも明示的な Deny があれば、必ず拒否(Allowより優先) |
さらに、組織やアカウント全体で使う仕組みがある場合は、それぞれが許可している範囲の重なりだけが実際に使えます。
| 仕組み | 役割 |
|---|---|
| アイデンティティベースのポリシー | ユーザーやロールに付けるポリシー(この記事の主題) |
| リソースベースのポリシー | S3バケットポリシーなど、リソース側に付けるポリシー |
| SCP(サービスコントロールポリシー) | AWS Organizationsで、アカウントごとに使える範囲の上限を決める |
| アクセス許可の境界(Permissions Boundary) | ユーザーやロールが持てる権限の上限を決める |
| セッションポリシー | 一時的な認証情報に付ける、さらなる制限 |
SCPやアクセス許可の境界は「上限」を決めるもので、それ自体では許可を与えません。「ポリシーでAllowしたのに動かない」ときは、SCPや境界で制限されていないかも確認します。
例文1:S3の特定のフォルダだけ読める
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ListReportsBucket",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::example-reports",
"Condition": { "StringLike": { "s3:prefix": ["monthly/*"] } }
},
{
"Sid": "ReadMonthlyReports",
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::example-reports/monthly/*"
}
]
}
一覧の取得(ListBucket)はバケットのARN、ファイルの読み取り(GetObject)はオブジェクトのARN(末尾に /*)と、対象が違う点がポイントです。ここを取り違えるのが、S3で最も多い間違いです。
例文2:タグが dev のEC2だけ起動・停止できる
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "StartStopDevInstancesOnly",
"Effect": "Allow",
"Action": ["ec2:StartInstances", "ec2:StopInstances"],
"Resource": "arn:aws:ec2:ap-northeast-1:123456789012:instance/*",
"Condition": { "StringEquals": { "aws:ResourceTag/Env": "dev" } }
},
{
"Sid": "DescribeAll",
"Effect": "Allow",
"Action": "ec2:DescribeInstances",
"Resource": "*"
}
]
}
タグで対象を絞る(ABAC:属性ベースのアクセス制御)と、インスタンスが増えてもポリシーを書き換えずに済みます。一覧の表示(DescribeInstances)はリソースを指定できない操作のため、"*" を指定しています。
例文3:東京リージョン以外での操作を禁止する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyOutsideTokyo",
"Effect": "Deny",
"NotAction": ["iam:*", "sts:*", "support:*", "cloudfront:*", "route53:*"],
"Resource": "*",
"Condition": { "StringNotEquals": { "aws:RequestedRegion": "ap-northeast-1" } }
}
]
}
Deny と NotAction を組み合わせると、「特定の操作以外は、条件に合わなければ拒否」という書き方ができます。IAMやCloudFrontのようにリージョンに関係しないグローバルなサービスは、NotActionで除外しておかないと使えなくなる点に注意します。
例文4:MFAを使っていなければ、ほぼすべて拒否する
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DenyWithoutMFA",
"Effect": "Deny",
"NotAction": [
"iam:ChangePassword", "iam:GetUser", "iam:ListMFADevices",
"iam:CreateVirtualMFADevice", "iam:EnableMFADevice", "sts:GetSessionToken"
],
"Resource": "*",
"Condition": { "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" } }
}
]
}
MFAを設定するために必要な操作だけを除外し、それ以外はMFAで認証していなければ拒否します。BoolIfExists を使うのは、条件のキー自体がないリクエストも拒否の対象にするためです。
よくある間違い:リンターで検査してみた
次のポリシーを、IAMポリシーのリンター(parliament)で検査しました。
{
"Version": "2012-10-17",
"Statement": [
{ "Effect": "Allow", "Action": "s3:*", "Resource": "*" },
{ "Effect": "Allow", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::example-reports" }
]
}
| 検出された指摘 | 意味 |
|---|---|
RESOURCE_STAR |
s3:* をすべてのリソースに許可している。削除などの危険な操作も含まれる |
RESOURCE_MISMATCH |
s3:GetObject の対象が、オブジェクトの形式(arn:*:s3:::*/*)になっていない |
2つ目は、書いても効果がない(何も許可されない)ポリシーです。「許可したのに読めない」ときは、まずResourceの形式を疑います。この記事の例文1〜4は、同じリンターで指摘がないことを確認しています。
| よくある間違い | 正しい書き方 |
|---|---|
GetObject の Resource にバケットのARN |
arn:aws:s3:::バケット名/*(末尾に /*) |
ListBucket の Resource にオブジェクトのARN |
arn:aws:s3:::バケット名(/* なし) |
"Action": "*" と "Resource": "*" の組み合わせ |
必要な操作とリソースだけに絞る |
| Allowを足しても動かない | 別の場所に明示的なDeny、SCP、アクセス許可の境界がないか確認 |
| 条件のキーの名前の打ち間違い | IAMでは存在しないキーでもエラーにならないことがある。リンターやポリシーの検証で確認 |
最小権限を作る手順
最初から完璧な最小権限を書くのは難しいため、段階的に絞っていくのが現実的です。
| 手順 | 内容 |
|---|---|
| 1. 使う操作を洗い出す | アプリやジョブが呼ぶAWSのAPIを一覧にする |
| 2. 対象のリソースを絞る | "*" ではなく、ARNで対象を指定する |
| 3. 条件で絞る | タグ、リージョン、送信元などで範囲を狭める |
| 4. 実際の利用状況で確認する | IAM Access Analyzerで、CloudTrailの記録からポリシーを生成したり、使われていない権限を確認したりする |
| 5. ポリシーを検証する | IAM Access Analyzerのポリシー検証で、文法やセキュリティ上の指摘を確認する |
| 6. 定期的に見直す | 使われなくなった権限を削除する |
人には「ユーザーに直接ポリシーを付ける」より、「ロールを引き受けて使う」形を基本にすると、権限の管理と監査がしやすくなります。アプリケーションも、アクセスキーを埋め込むのではなく、EC2やLambdaなどに割り当てたロールから一時的な認証情報を使います。
AWS管理ポリシーとカスタマー管理ポリシー
| 種類 | 特徴 | 向いている場面 |
|---|---|---|
| AWS管理ポリシー | AWSが作成・更新する(ReadOnlyAccess など) |
検証、職務ごとの大まかな権限 |
| カスタマー管理ポリシー | 自分で作成し、複数のロールで使い回せる | 本番の最小権限 |
| インラインポリシー | 1つのユーザーやロールに直接埋め込む | ほかで使い回さない、特別な権限 |
AWS管理ポリシーは便利ですが、必要以上に広いことが多いため、本番ではカスタマー管理ポリシーで絞るのが基本です。
よくある質問
Q. Versionの "2012-10-17" は変えなくていいのですか?
A. 変えません。これはポリシーの文法のバージョンで、現在の最新です。書かないと古い文法として扱われ、${aws:username} のような変数が使えなくなります。
Q. ポリシーの動作を試す方法はありますか? A. IAMポリシーシミュレーターで、特定の操作が許可されるかを確認できます。IAM Access Analyzerのポリシー検証も、書いたポリシーの問題点を指摘してくれます。
Q. AIにポリシーを書かせてもいいですか?
A. 下書きには役立ちます。ただし、Resourceが "*" になっていないか、不要な操作が含まれていないかは人が確認し、ポリシーの検証とリンターにかけてから使います。
まとめ
- IAMポリシーは、Effect・Action・Resource・Conditionで「誰が何をどこにどんな条件で」を決める
- 何も書かなければ拒否。明示的なDenyは、どんなAllowよりも優先
- SCPやアクセス許可の境界は「上限」。許可を与えるものではない
- S3は ListBucketはバケット、GetObjectはオブジェクト(
/*) のARN - タグで絞る、リージョンで絞る、MFAを必須にするなどを Condition で書ける
- 最小権限は、Access Analyzerで実際の利用状況を見ながら段階的に絞る
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「IAMポリシーの書き方|JSONの読み方と最小権限の作り方【例文つき】」
株式会社RJCでは、クラウドを安全に使うための知識を、プロジェクトやグループ活動の中で仲間と学び合っています。こうした知識を共有しながら、日々技術を磨いています。
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。