ポリシーJSONを一行ずつ解体する
一言でいうと
ポリシーは結局、次の4つを書くドキュメントです。何を(Action)どこに(Resource)許可または拒否(Effect)するか、どんな条件で(Condition)行うかです。
なぜ必要なのか
ポリシーは、文法上は有効でも、意図より広く開くことがあります。許可の効果だけを確認して、リソースの範囲と条件を読まないと、レビューを通ったポリシーが、そのまま権限昇格の経路になります。そのため、ポリシーを構成要素ごとに分解し、危険な組み合わせを決まった順序で読む必要があります。
どう動くのか
最小の形
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadReportsOnly",
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::acme-reports",
"arn:aws:s3:::acme-reports/*"
]
}
]
}
Versionは日付のように見えますが、ポリシー言語のバージョンです。2012-10-17をそのまま使います。変えると、変数置換のような機能が使えなくなります。
Resourceが2行ある理由
これが、初心者が最も間違える場所です。
arn:aws:s3:::acme-reports: バケット自体。ListBucketがここに必要です。arn:aws:s3:::acme-reports/*: バケットの中のオブジェクト。GetObjectがここに必要です。
2つは別のリソースです。1つだけ書くと、「一覧は見えるのにファイルが開けない」、またはその逆になります。
ARNの構造
arn:aws:s3:::acme-reports/reports/2026/*
│ │ │ │ │ └ 자원 경로
│ │ │ │ └ 계정 ID (S3 는 비움)
│ │ │ └ 리전 (S3 는 전역이라 비움)
│ │ └ 서비스
│ └ 파티션 (aws / aws-cn / aws-us-gov)
└ 고정
空欄があるのはタイプミスではなく、そのサービスがグローバルだという意味です。
ワイルドカード: 危険は場所によって違う
| 表現 | 意味 | 危険度 |
|---|---|---|
"Action": "s3:Get*" |
読み取り系すべて | 低い |
"Action": "s3:*" |
S3のすべての操作(削除を含む) | 高い |
"Action": "*" |
すべてのサービスのすべての操作 | 管理者 |
"Resource": "*" |
すべてのリソース | 文脈による |
"Action": "*"と"Resource": "*"が1つの文に一緒にあれば、それは管理者権限です。ポリシーレビューで最初に探すべき組み合わせです。
Condition: 本当に絞られる場所
権限を絞る最も強力な手段なのに、最も使われていません。
"Condition": {
"IpAddress": { "aws:SourceIp": ["203.0.113.0/24"] },
"Bool": { "aws:SecureTransport": "true" },
"StringEquals": { "aws:PrincipalTag/team": "platform" },
"DateLessThan": { "aws:CurrentTime": "2026-12-31T00:00:00Z" }
}
- オフィスのIPからだけ
- HTTPSでだけ(これ1つで、平文のアクセスが塞がれます)
- 特定のチームタグを持つプリンシパルだけ
- 有効期限までだけ。一時的なアクセスに特に役立ちます
1つのConditionブロックの中の複数のキーはANDで結ばれ、1つのキーに値が複数あればORです。このルールを混同すると、意図と正反対のポリシーができます。
NotActionは落とし穴
{ "Effect": "Allow", "NotAction": "iam:*", "Resource": "*" }
「IAM以外すべて許可」と読めますが、実際には、これから生まれるすべての新しいサービスも自動的に許可されます。許可リストではなく拒否リストだからです。権限は常に、許可リストとして書きます。
読む順序
レビューのとき、この順序で見ると速いです。
Effect: Denyの文から。何が絶対に塞がれているかActionに*があるかResourceに*があるかConditionがあるか。なければ、その権限はどこからでも通りますNotAction/NotResourceがあるか。あれば疑います
現場での姿
- 一覧は見えるのにダウンロードできない →
Resourceに/*が抜けていました。 - ポリシーは合っているのに塞がれる → 上位の組織ポリシーのDenyか、権限境界です。
s3:*で付けて、忘れてしまった → 削除権限まで開いています。
次に見ること
長期のキーを配らなくても権限を与える方法。ロールと一時的な資格情報です。