IAM and least privilege · Cloud and Reliability
Who is allowed to do what in a cloud account?
Course contentsWhy you need it
Cloud accounts are controlled by permission policies. A policy that's too broad turns one leaked key or one bug into access to everything: every bucket, every database, every bill. Least privilege, giving each app exactly what it needs and nothing more, is one of the most effective security habits there is, and it starts with reading policies correctly.
The intuition
A policy is a list of statements. Each says: for these actions on these resources, Allow (or Deny). Wildcards are common: s3:Get*, photos/*.
policy = [
{"effect": "Allow", "actions": ["s3:GetObject", "s3:PutObject"], "resources": ["shop-photos/*"]},
{"effect": "Deny", "actions": ["s3:*"], "resources": ["shop-photos/private/*"]},
]Evaluation works like AWS IAM, simplified:
- Find the statements that match both the action and the resource.
- If any matching statement is a Deny → denied. An explicit deny always wins.
- Otherwise, if any is an Allow → allowed.
- Otherwise → denied. Nothing is allowed unless something allows it (implicit deny).
Least privilege in practice: list what the app really does (read photos, upload photos) and allow only those actions on only those resources. "actions": ["*"], "resources": ["*"] is the opposite.
Definition
Policy
A list of statements that allow or deny actions on resources.
Explicit deny
A matching Deny statement. It overrides every Allow.
Least privilege
Granting only the actions and resources a job needs, nothing more.
Examples
Wildcards
Try it yourselffnmatch matches * and ? the same way IAM patterns do.
import fnmatch
print(fnmatch.fnmatchcase("s3:GetObject", "s3:Get*"))
print(fnmatch.fnmatchcase("s3:PutObject", "s3:Get*"))
print(fnmatch.fnmatchcase("shop-photos/cats/1.jpg", "shop-photos/*"))
print(fnmatch.fnmatchcase("shop-photos", "shop-photos/*"))True False True False
- L3
- matches any characters: Object.
True - L5
- also crosses / here, so everything under the folder matches.
True - L6The pattern needs a / after the name, so the bucket itself doesn't match.
False
Allow, deny, and nothing
Try it yourselfAn explicit deny beats an allow; no match means no.
import fnmatch
def matches(patterns, value):
return any(fnmatch.fnmatchcase(value, p) for p in patterns)
def allowed(policy, action, resource):
hits = [s for s in policy if matches(s["actions"], action) and matches(s["resources"], resource)]
if any(s["effect"] == "Deny" for s in hits):
return False
return any(s["effect"] == "Allow" for s in hits)
policy = [
{"effect": "Allow", "actions": ["s3:GetObject", "s3:PutObject"], "resources": ["shop-photos/*"]},
{"effect": "Deny", "actions": ["s3:*"], "resources": ["shop-photos/private/*"]},
]
print(allowed(policy, "s3:GetObject", "shop-photos/cat.jpg"))
print(allowed(policy, "s3:GetObject", "shop-photos/private/id.png"))
print(allowed(policy, "s3:DeleteObject", "shop-photos/cat.jpg"))True False False
- L7Statements matching both the action and the resource.
- L8Any matching deny wins.
- L18Both statements match; the Deny wins.
False - L19Nothing allows deleting: implicit deny.
False
Common mistakes
"*" on "*"
An app with full access turns any bug or leaked key into a full account takeover. List the actions it really uses.
Expecting Allow to beat Deny
An explicit Deny always wins, wherever it comes from. That's how guardrails like "never delete backups" work.
Long-lived keys
Access keys that never expire leak eventually. Prefer roles with short-lived credentials, and rotate any key that must exist.
Quick quiz
1. One statement allows `s3:*` on `logs/*`; another denies `s3:DeleteObject` on `logs/*`. Can the app delete `logs/a.txt`?
Show the answer
Answer: A
Order doesn't matter. Any matching Deny overrides every Allow.
2. A policy only allows `s3:GetObject`. What happens on `s3:PutObject`?
Show the answer
Answer: A
Implicit deny: anything not allowed is refused.
Practice
3 exercises in three steps: predict what a program prints, change a program to meet a new requirement, then write one from scratch. Your code runs in the browser and is checked the moment you submit.
- PredictDecide each request
Type exactly what this prints.
- ModifyLeast privilege
The photo app only needs to read and upload files under
shop-photos/uploads/. Its policy allows everything. ReplacePOLICYwith one that allows exactlys3:GetObjectands3:PutObjectonshop-photos/uploads/*. - WriteEvaluate a policy
Write
allowed(policy, action, resource)yourself. Each statement has"effect"("Allow"or"Deny"),"actions"and"resources"(lists of patterns with*and?). Rules:- a statement applies if any action pattern matches
actionand any resource pattern matchesresource - any applying Deny →
False - else any applying Allow →
True - else
False
Use
fnmatch.fnmatchcase(value, pattern)for matching. - a statement applies if any action pattern matches
Practise this lesson
Open the interactive lesson to edit and run these examples and solve the exercises with instant feedback. Free to start, no sign-up.
Interactive lessons open in order. If you have not done the earlier ones yet, you start at the course map.
Terms in this lesson
| Term | Chinese | Definition |
|---|---|---|
| IAM | 身份与访问管理 | Identity and access management: who may do what in a cloud account. |
| Least privilege | 最小权限 | Only the permissions a job needs. |
| Implicit deny | 隐式拒绝 | Anything not explicitly allowed is refused. |