権限を手で計算する
目標
IAMはクラウド事故の最大の原因ですが、判断のロジック自体は3行です。
1. 명시적 Deny 가 하나라도 맞으면 → 거부
2. 아니고 Allow 가 하나라도 맞으면 → 허용
3. 둘 다 없으면 → 거부 (암묵적 거부)
順序ではなく種類が勝ちます。ポリシーをいくつ付けても、Deny1つがすべてのAllowに勝ちます。
このラボは、クラウドアカウントなしで、このロジックをそのまま動かします。
評価器
python3 /opt/lab/iam/evaluate.py policy.json requests.txt
リクエストファイルは、1行に액션 리소스(プレースホルダーはアクションとリソースです)で、条件は키=값(プレースホルダーはキーと値です)として付け足します。
s3:GetObject arn:aws:s3:::reports/2026-q1.csv
s3:GetObject arn:aws:s3:::pub/x aws:SourceVpc=vpc-lab1
評価器のソースも読んでみてください。200行もありません。IAMが難しいのは、ロジックが複雑だからではなく、ポリシーが複数の場所で合成されるからです。
用意されたファイル
| ファイル | 用途 |
|---|---|
/opt/lab/iam/evaluate.py |
評価器 |
/opt/lab/iam/policy1.json・requests1.txt |
ステップ1 |
/opt/lab/iam/needed.txt |
ステップ4。アプリが実際にやること |
/opt/lab/iam/incident.json |
ステップ6 |
参考
ステップ4は、書かれていないリクエストでもテストします。広く書くと、そこで引っかかります。
結果を先に予測する
/opt/lab/iam/policy1.jsonと/opt/lab/iam/requests1.txtを見て、評価器を実行する前に、各リクエストの結果を01-predict.txtにallowまたはdenyで1行ずつ書いてください。そして、結果が意外だったもの2つを選んで、なぜそうなるのかを01-why.mdに1行ずつ書いてください。
ルールは3行です。明示的なDeny > 明示的なAllow > 暗黙のDeny。順序ではなく種類が勝ちます。
書き終えたあとで、python3 /opt/lab/iam/evaluate.py /opt/lab/iam/policy1.json /opt/lab/iam/requests1.txtで合わせてみてください。採点ツールは、予測が評価器とすべて一致したときだけ合格にします。
意外な場所は、たいてい次の3つのうちのどれかです。s3:*を与えたのに塞がれたもの、どの文にも当てはまらなくて塞がれたもの、条件キーがなくて塞がれたものです。
Denyは順序と無関係に勝つ
同じアクションをAllowする文とDenyする文が入ったポリシーを作り、Denyの文を上に置いたものと下に置いたものの2つを作って、結果が同じであることを02-deny.txtに残してください。
ファイルはdeny-first.jsonとdeny-last.jsonとして作り、同じリクエストに対する2つの結果を一緒に書いてください。ポリシーをいくつ付けても、Deny1つがすべてのAllowに勝ちます。そのため、「権限をさらに付けたのになぜ通らないのか」の答えは、たいてい、どこかのDenyです。
ワイルドカードはどこまで拾うか
arn:aws:s3:::app-data*をリソースに使ったポリシーが、app-data-secretまで拾うことを示し、意図したバケットだけを拾うように直して、03-wildcard.txtに両方を残してください。
*はスラッシュも越えます。app-data*は、app-data、app-data-dev、app-data-secretバケットをすべて拾います。
直す方法は、区切り文字を明示することです。arn:aws:s3:::app-data/*のようにです。実際の流出事故によくある形です。
最小権限に絞る
/opt/lab/iam/needed.txtに、このアプリが実際にやることが書かれています。それだけが通り、残りは通らないポリシーを、least.jsonとして書いてください。アクションに*を使ってはいけません。
採点ツールは、needed.txtだけでなく、書かれていない隣接リクエストでもテストします。同じバケットの削除や、名前が似ている別のバケットのようなものです。広く書くと、そこで引っかかります。
最小権限は「少し絞ること」ではなく、必要なものを書き出して、それだけを許可することです。順序が逆だと、絶対に絞れません。
条件をかける
ステップ4のポリシーに、会社のVPC(vpc-lab1)から来たリクエストだけを許可する条件を加えて、cond.jsonとして書いてください。
"Condition": {"StringEquals": {"aws:SourceVpc": "vpc-lab1"}}。条件キーがそもそもないリクエストは、StringEqualsを満たせず、拒否されます。それが正しい動作です。資格情報が外に漏れても、その資格情報だけでは使えないようにする仕組みです。
事故を再現する
/opt/lab/iam/incident.jsonに、実際によくあるミスが入っています。何がなぜ危険かを見つけて06-incident.txtに書き、その危険を証明するリクエスト1行も一緒に残してください。
評価器であれこれ入れてみてください。意図したよりはるかに多くのものが通ります。答えを見つけたら、このポリシーを書いた人が、なぜ安全だと信じたのかも考えてみてください。その勘違いが、事故の本当の原因です。
3つをまとめる
07-notes.mdに3行以上。評価ルールの3行、ワイルドカードで気をつけること、条件が防いでくれるもの。
本文にDeny、와일드카드、조건が含まれている必要があります(韓国語で、2つ目は「ワイルドカード」、3つ目は「条件」を意味する語です)。