TT Lab
Get started
Learn Learning paths Courses

Cloud Permission Design

Compute the Permission by Hand

Continue in TT Lab

Goal

IAM is the number one cause of cloud incidents, yet the decision logic itself is three lines.

1. 명시적 Deny 가 하나라도 맞으면  → 거부
2. 아니고 Allow 가 하나라도 맞으면 → 허용
3. 둘 다 없으면                    → 거부 (암묵적 거부)

Kind wins, not order. No matter how many policies you attach, a single Deny beats every Allow.

This lab runs this logic as is, without a cloud account.

The evaluator

python3 /opt/lab/iam/evaluate.py policy.json requests.txt

Each line of the request file is 액션 리소스 (action, resource), and conditions are appended as 키=값 (key=value).

s3:GetObject arn:aws:s3:::reports/2026-q1.csv
s3:GetObject arn:aws:s3:::pub/x aws:SourceVpc=vpc-lab1

Read the evaluator's source too — it is under 200 lines. IAM is hard not because the logic is complicated but because policies are combined from many places.

Prepared files

File Use
/opt/lab/iam/evaluate.py The evaluator
/opt/lab/iam/policy1.json · requests1.txt Step 1
/opt/lab/iam/needed.txt Step 4 — what the app actually does
/opt/lab/iam/incident.json Step 6

Notes

Step 4 is also tested with requests that are not listed. If you write broadly, you get caught there.

Predict the results first

Look at /opt/lab/iam/policy1.json and /opt/lab/iam/requests1.txt, and before running the evaluator, write the result of each request to 01-predict.txt, one per line, as allow or deny. Then pick two results that surprise you and write one line each on why in 01-why.md.

There are three rules — explicit Deny > explicit Allow > implicit Deny. Kind wins, not order.

After you have written them all, check against python3 /opt/lab/iam/evaluate.py /opt/lab/iam/policy1.json /opt/lab/iam/requests1.txt. The grader passes you only when your predictions all match the evaluator.

The surprising spots are usually one of three — one blocked even though you gave s3:*, one blocked because it matched no statement, and one blocked because the condition key was missing.

Deny wins regardless of order

Make policies that contain a statement that allows the same action and a statement that denies it, but make two — one with the Deny statement above and one with it below — and leave in 02-deny.txt the fact that the results are the same.

Name the files deny-first.json and deny-last.json, and write the two results for the same request together. No matter how many policies you attach, a single Deny beats every Allow. That is why the answer to "I added more permissions, so why doesn't it work" is usually a Deny somewhere.

How far does a wildcard reach

Show that a policy using arn:aws:s3:::app-data* as its resource also matches app-data-secret, fix it so that it matches only the intended bucket, and leave both in 03-wildcard.txt.

* also crosses slashes. app-data* matches app-data, app-data-dev and app-data-secret, all of them.

The fix is to state the delimiter explicitly — like arn:aws:s3:::app-data/*. This is a common shape of real leak incidents.

Narrow it to least privilege

What this app actually does is written in /opt/lab/iam/needed.txt. Write a policy in least.json that allows only that and nothing else. You must not use * in the action.

The grader tests not only needed.txt but also adjacent requests that are not listed — things such as deleting in the same bucket, or another bucket with a similar name. If you write broadly, you get caught there.

Least privilege is not "narrowing a little" but writing what is needed and allowing only that. If the order is reversed, it never gets narrowed.

Attach a condition

Add to the step 4 policy a condition that allows only requests from the company VPC (vpc-lab1), and write it to cond.json.

"Condition": {"StringEquals": {"aws:SourceVpc": "vpc-lab1"}}. A request that has no condition key at all cannot satisfy StringEquals and is denied — that is the correct behavior. It is a device that makes leaked credentials unusable on their own.

Reproduce the incident

/opt/lab/iam/incident.json contains a mistake that is truly common. Find what is dangerous and why, write it in 06-incident.txt, and leave one request line that proves the danger as well.

Try various things in the evaluator. Far more passes than was intended. When you find the answer, also think about why the person who wrote this policy believed it was safe — that misconception is the real cause of the incident.

Summarize the three points

Write at least three lines in 07-notes.md: the three evaluation rules, what to be careful about with wildcards, and what conditions protect against.

The text must include Deny, 와일드카드 (wildcard) and 조건 (condition).