Compute the Permission by Hand
한국어 원문으로 표시합니다.
목표
IAM 은 클라우드 사고의 1번 원인인데, 결정 논리 자체는 세 줄입니다.
1. 명시적 Deny 가 하나라도 맞으면 → 거부
2. 아니고 Allow 가 하나라도 맞으면 → 허용
3. 둘 다 없으면 → 거부 (암묵적 거부)
순서가 아니라 종류가 이깁니다. 정책을 몇 개 붙이든 Deny 하나가 모든 Allow 를 이깁니다.
이 실습은 클라우드 계정 없이 이 논리를 그대로 돌립니다.
평가기
python3 /opt/lab/iam/evaluate.py policy.json requests.txt
요청 파일은 한 줄에 액션 리소스, 조건은 키=값 으로 덧붙입니다.
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 로 한 줄씩 적으세요. 그리고 결과가 뜻밖인 것 두 개를 골라 왜 그런지 01-why.md 에 한 줄씩 적으세요.
규칙은 세 줄입니다 — 명시적 Deny > 명시적 Allow > 암묵적 Deny. 순서가 아니라 종류가 이깁니다.
다 적은 뒤에 python3 /opt/lab/iam/evaluate.py /opt/lab/iam/policy1.json /opt/lab/iam/requests1.txt 로 맞춰 보세요. 채점기는 당신의 예측이 평가기와 전부 일치할 때만 통과시킵니다.
뜻밖인 자리는 대개 셋 중 하나입니다 — s3:* 를 줬는데도 막힌 것, 아무 문장에도 안 걸려서 막힌 것, 조건 키가 없어서 막힌 것.
Deny 는 순서와 무관하게 이긴다
같은 액션을 Allow 하는 문장과 Deny 하는 문장이 든 정책을 만들되, Deny 문장을 위에 둔 것과 아래 둔 것 두 개를 만들어 결과가 같은 것을 02-deny.txt 에 남기세요.
파일은 deny-first.json 과 deny-last.json 으로 만들고, 같은 요청에 대한 두 결과를 함께 적으세요. 정책을 몇 개 붙이든 Deny 하나가 모든 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 에 적고, 그 위험을 증명하는 요청 한 줄도 함께 남기세요.
평가기로 이것저것 넣어 보세요. 의도한 것보다 훨씬 많은 것이 통과합니다. 답을 찾으면 왜 이 정책을 쓴 사람이 안전하다고 믿었는지도 생각해 보세요 — 그 착각이 사고의 진짜 원인입니다.
세 가지를 정리한다
07-notes.md 에 세 줄 이상. 평가 규칙 세 줄, 와일드카드에서 조심할 것, 조건이 막아 주는 것.
본문에 Deny, 와일드카드, 조건 이 들어가야 합니다.