ЁЯПл The SchoolтА║ЁЯкк IAMтА║ЁЯСе рдзрдбрд╛ 02 тАФ Users, groups рдЖрдгрд┐ root: рдХрд╛рд░реНрдбреЗ рдЖрдгрд┐ рд╡рд░реНрдЧрд╛рдЪреНрдпрд╛ рдпрд╛рджреНрдпрд╛
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯСе рдзрдбрд╛ 02 тАФ Users, groups рдЖрдгрд┐ root: рдХрд╛рд░реНрдбреЗ рдЖрдгрд┐ рд╡рд░реНрдЧрд╛рдЪреНрдпрд╛ рдпрд╛рджреНрдпрд╛

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 02 ┬╖ рдорд╛рдЧреЗ: lesson-01-why-iam ┬╖ рдкреБрдвреЗ: lesson-03-policies


ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ

рдзрдбрд╛ 01, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд рдкрд╣рд┐рд▓реНрдпрд╛ identities: IAM users (aishwarya, katrina, dipika), policies рд╡рд╛рд╣реВрди рдиреЗрдгрд╛рд░рд╛ рдПрдХ group (teachers), рдЖрдгрд┐ рддреБрдореНрд╣реА рддрд┐рдЬреЛрд░реАрдд рдмрдВрдж рдХрд░реВрди рдареЗрд╡рддрд╛ рддреЛ root user. iam/demo.py рдордзрд▓рд╛ users() рджрд╛рдЦрд╡рддреЛ рдХреА рдкрд░рд╡рд╛рдирдЧреНрдпрд╛ рдпрд╛рджреАрдиреБрд╕рд╛рд░ рдЪрд╛рд▓рддрд╛рдд.

ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ

рдУрд│рдЦрдкрддреНрд░ рдХрд╛рд░реНрдпрд╛рд▓рдп рд╢рд╛рд│реЗрддрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рдореЛрдареНрдпрд╛ рд╡реНрдпрдХреНрддреАрд▓рд╛ рддрд┐рдЪреНрдпрд╛ рдирд╛рд╡рд╛рдЪреЗ рдПрдХ рдХрд╛рд░реНрдб рджреЗрддреЗ тАФ рддреЗрдЪ IAM user. "рдРрд╢реНрд╡рд░реНрдпрд╛ рдЧреНрд░рдВрдерд╛рд▓рдп рдЙрдШрдбреВ рд╢рдХрддреЗ" рд╣реЗ рдРрд╢реНрд╡рд░реНрдпрд╛рдЪреНрдпрд╛рдЪ рдХрд╛рд░реНрдбрд╡рд░ рд▓рд┐рд╣рд┐рдгреЗ рджрдорд╡рдгрд╛рд░реЗ рдЕрд╕рддреЗ: рдирд╡реА рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рдЖрд▓реА рдХреА рдкреБрдиреНрд╣рд╛ рд▓рд┐рд╣рд╛, рдЖрдгрд┐ рдХреЛрдгреА рд╕реЛрдбреВрди рдЧреЗрд▓реЗ рдХреА рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдб рд╢реЛрдзрдд рдмрд╕рд╛.

рдореНрд╣рдгреВрди рдХрд╛рд░реНрдпрд╛рд▓рдп рддреНрдпрд╛рдРрд╡рдЬреА рд╡рд░реНрдЧрд╛рдЪреНрдпрд╛ рдпрд╛рджреНрдпрд╛ ЁЯУЛ рдареЗрд╡рддреЗ. рдирд┐рдпрдо рдпрд╛рджреАрд▓рд╛ рд▓рд╛рд╡рд▓реЗрд▓реЗ рдЕрд╕рддрд╛рдд тАФ "teachers рдпрд╛рджреАрддреАрд▓ рдкреНрд░рддреНрдпреЗрдХрдЬрдг reports рд╡рд╛рдЪреВ рд╢рдХрддреЛ" тАФ рдЖрдгрд┐ рд▓реЛрдХ рдлрдХреНрдд рдпрд╛рджреАрдд рдпреЗрддрд╛рдд рдХрд┐рдВрд╡рд╛ рдЬрд╛рддрд╛рдд. рджреАрдкрд┐рдХрд╛ teachers рдордзреНрдпреЗ рд╕рд╛рдореАрд▓ рд╣реЛрддреЗ: рддреА reports рд╡рд╛рдЪреВ рд╢рдХрддреЗ. рддреА рдмрд╛рд╣реЗрд░ рдкрдбрддреЗ: рддреА рд╡рд╛рдЪреВ рд╢рдХрдд рдирд╛рд╣реА.

рдЖрдгрд┐ рдорд╛рд╕реНрдЯрд░ рдЪрд╛рд╡реА ЁЯЧЭя╕П тАФ рдкреНрд░рддреНрдпреЗрдХ рджрд╛рд░ рдЙрдШрдбрдгрд╛рд░реА, рд╢рд╛рд│рд╛ рдмрд╛рдВрдзрд▓реА рддреЗрд╡реНрд╣рд╛ рдмрдирд╡рд▓реЗрд▓реА тАФ рддреА рджреБрд╕рд▒реНрдпрд╛ рдХреБрд▓реБрдкрд╛рд╕рд╣ (MFA) рддрд┐рдЬреЛрд░реАрдд рдЬрд╛рддреЗ. рддреЛрдЪ root user.

ЁЯЧ║я╕П рдЖрдХреГрддреА

flowchart LR
    root["ЁЯЧЭя╕П root user<br/>MFA ┬╖ no access keys ┬╖ in the safe"]
    grp["ЁЯУЛ group: teachers<br/>read-reports ┬╖ own-homework-folder"]
    a["ЁЯкк aishwarya"] --> grp
    s["ЁЯкк katrina"] --> grp
    k["ЁЯкк dipika<br/>no groups"]
    grp -->|"1 policies apply to members"| ok["тЬЕ s3:GetObject report"]
    k -.->|"2 nothing attached"| no["ЁЯЪл IMPLICIT DENY"]

ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/iam/lesson-diagrams.html#l02

тЭУ рдХрд╛рдп

ЁЯдФ рдХрд╛

рд╡реНрдпрдХреНрддреАрдВрдирд╛ рд▓рд╛рд╡рд▓реЗрд▓реНрдпрд╛ рдкрд░рд╡рд╛рдирдЧреНрдпрд╛ рднрд░рдХрдЯрддрд╛рдд: рдХреЛрдгреА team рдмрджрд▓рддреЗ рдЖрдгрд┐ рдЬреБрдиреЗ рдЕрдзрд┐рдХрд╛рд░ рддрд╕реЗрдЪ рдареЗрд╡рддреЗ, рд╕реЛрдбреВрди рдЧреЗрд▓реЗрд▓реНрдпрд╛рдХрдбреЗ key рд░рд╛рд╣рддреЗ. рдпрд╛рджреНрдпрд╛рдВрдирд╛ рд▓рд╛рд╡рд▓реЗрд▓реНрдпрд╛ рдкрд░рд╡рд╛рдирдЧреНрдпрд╛ рдПрдХрджрд╛ рддрдкрд╛рд╕рд▓реНрдпрд╛ рдЬрд╛рддрд╛рдд рдЖрдгрд┐ рдпрд╛рджреАрддреАрд▓ рд╕рдЧрд│реНрдпрд╛рдВрдирд╛ рд▓рд╛рдЧреВ рд╣реЛрддрд╛рдд. рдЖрдгрд┐ рд░реЛрдЬ рд╡рд╛рдкрд░рд▓рд╛ рдЬрд╛рдгрд╛рд░рд╛ root user рдореНрд╣рдгрдЬреЗ рдЦрд┐рд╢рд╛рдд рдареЗрд╡рд▓реЗрд▓реА рдорд╛рд╕реНрдЯрд░ рдЪрд╛рд╡реА.

ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)

iam/demo.py рдордзреНрдпреЗ GROUPS рд╣реЗ teachers рд▓рд╛ рджреЛрди policies рд╢реА рдЬреЛрдбрддреЗ рдЖрдгрд┐ MEMBERS рдпрд╛рджреАрдд рдХреЛрдг рдЖрд╣реЗ рддреЗ рд╕рд╛рдВрдЧрддреЗ; policies_of(name) user рдЪреНрдпрд╛ groups рдордзреВрди рддреНрдпрд╛рдЪреНрдпрд╛ policies рдЧреЛрд│рд╛ рдХрд░рддреЗ. users() рддреАрди рдЬрдгрд╛рдВрд╕рд╛рдареА рддреЛрдЪ рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддреЛ, рдордЧ dipika рд▓рд╛ рдпрд╛рджреАрдд рдЬреЛрдбрддреЛ рдЖрдгрд┐ рдкреБрдиреНрд╣рд╛ рд╡рд┐рдЪрд╛рд░рддреЛ.

ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛

python3 iam/demo.py users
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
groups = {"teachers": ["read-reports", "own-homework-folder"], "exam-board": ["deny-delete-reports"]}
def policies(*gs): return [(p, load(p)) for g in gs for p in groups[g]]
dipika, notes = "arn:aws:iam::111122223333:user/dipika", "arn:aws:s3:::school-homework/dipika/notes.txt"
print("no groups         ", decide(dipika, "s3:PutObject", notes, identity=policies())[0])
print("teachers          ", decide(dipika, "s3:PutObject", notes, identity=policies("teachers"))[0])
print("teachers + exams  ", decide(dipika, "s3:GetObject", "arn:aws:s3:::school-reports/term1.pdf", identity=policies("teachers", "exam-board"))[0])
EOF

рдЦрд▒реНрдпрд╛ account рд╡рд░ (AWS CLI рдЖрдгрд┐ credentials рд▓рд╛рдЧрддрд╛рдд):

aws iam create-group --group-name teachers
aws iam create-policy --policy-name read-reports --policy-document file://iam/policies/read-reports.json
aws iam attach-group-policy --group-name teachers --policy-arn arn:aws:iam::111122223333:policy/read-reports
aws iam create-user --user-name dipika
aws iam add-user-to-group --user-name dipika --group-name teachers
aws iam list-groups-for-user --user-name dipika
aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled'    # 1 = root has MFA

тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ

users рд╣реЗ aishwarya рдЖрдгрд┐ katrina рд╕рд╛рдареА тЬЕ ALLOW print рдХрд░рддреЛ (identity policy read-reports#ReadReports allows it), рдХреЛрдгрддреНрдпрд╛рд╣реА group рдордзреНрдпреЗ рдирд╕рд▓реЗрд▓реНрдпрд╛ dipika рд╕рд╛рдареА ЁЯЪл IMPLICIT DENY, рдЖрдгрд┐ dipika teachers рдордзреНрдпреЗ рд╕рд╛рдореАрд▓ рд╣реЛрддрд╛рдЪ тЬЕ ALLOW. рддреБрдордЪрд╛ snippet IMPLICIT DENY, ALLOW, ALLOW print рдХрд░рддреЛ тАФ рджреБрд╕рд▒реНрдпрд╛ group рдордзреНрдпреЗ рд╕рд╛рдореАрд▓ рдЭрд╛рд▓реНрдпрд╛рдиреЗ рдирд┐рдпрдо рд╡рд╛рдврддрд╛рдд; exam board рдЪрд╛ Deny рдлрдХреНрдд s3:DeleteObject рдмрджреНрджрд▓ рдЖрд╣реЗ, рдореНрд╣рдгреВрди рд╡рд╛рдЪрдгреЗ рдЪрд╛рд▓реВрдЪ рд░рд╛рд╣рддреЗ.

ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ

рдкрд░рд╡рд╛рдирдЧреНрдпрд╛ рдпрд╛рджреАрдиреБрд╕рд╛рд░ рдЪрд╛рд▓рддрд╛рдд: рдХреЛрдгреАрд╣реА policy рди рдмрджрд▓рддрд╛, рддреАрдЪ рд╡реНрдпрдХреНрддреА group рдордзреНрдпреЗ рдпреЗрдКрди рдХрд┐рдВрд╡рд╛ рдЬрд╛рдКрди access рдорд┐рд│рд╡рддреЗ рдХрд┐рдВрд╡рд╛ рдЧрдорд╛рд╡рддреЗ.

тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: auditors рд╕реБрд░реБрд╡рд╛рддреАрд▓рд╛рдЪ рджреЛрди рдкреНрд░рд╢реНрди рд╡рд┐рдЪрд╛рд░рддрд╛рдд тАФ "root user рдЪреЗ MFA рджрд╛рдЦрд╡рд╛ рдЖрдгрд┐ рддреНрдпрд╛рдЪреНрдпрд╛рдХрдбреЗ keys рдирд╛рд╣реАрдд рд╣реЗ рджрд╛рдЦрд╡рд╛" рдЖрдгрд┐ "рдкрд░рд╡рд╛рдирдЧреНрдпрд╛ рд╡реНрдпрдХреНрддреАрдВрдХрдбреВрди рдирд╛рд╣реА, рддрд░ groups рдХрд┐рдВрд╡рд╛ roles рдХрдбреВрди рдпреЗрддрд╛рдд рд╣реЗ рджрд╛рдЦрд╡рд╛". рджреЛрдиреНрд╣реА рд╕рд┐рджреНрдз рдХрд░рд╛рдпрд▓рд╛ рдПрдХрдЪ CLI call рдкреБрд░рддреЛ.

тПня╕П рдкреБрдвреЗ

рдирд┐рдпрдорд╛рд╡рд░ рдиреЗрдордХреЗ рдХрд╛рдп рд▓рд┐рд╣рд┐рд▓реЗрд▓реЗ рдЕрд╕рддреЗ? Policies тАФ рдкреНрд░рддреНрдпреЗрдХ statement рдордзреНрдпреЗ рдЕрд╕рдгрд╛рд░реА рдЪрд╛рд░ fields.

git checkout lesson-03-policies

ЁЯСе Lesson 02 тАФ Users, groups & root: cards and class lists

ЁЯУН You are here: Lesson 02 of 12 ┬╖ Previous: lesson-01-why-iam ┬╖ Next: lesson-03-policies


ЁЯУж What's in this branch

Lesson 01, plus the first identities: IAM users (aishwarya, katrina, dipika), a group (teachers) that carries the policies, and the root user you lock away. users() in iam/demo.py shows permissions following the list.

ЁЯзТ Explain like I'm 5

The ID office gives every grown-up in the school a card with their name on it тАФ that is an IAM user. Writing "Aishwarya may open the library" on Aishwarya's own card is tiring: when a new teacher joins you write it again, and when one leaves you hunt for every card.

So the office keeps class lists ЁЯУЛ instead. The rules are pinned to the list тАФ "everyone on the teachers list may read reports" тАФ and people just join or leave the list. Dipika joins teachers: she can read reports. She leaves: she cannot.

And the master key ЁЯЧЭя╕П тАФ the one that opens every door and was cut when the school was built тАФ goes in the safe, with a second lock (MFA). That is the root user.

ЁЯЧ║я╕П Diagram

flowchart LR
    root["ЁЯЧЭя╕П root user<br/>MFA ┬╖ no access keys ┬╖ in the safe"]
    grp["ЁЯУЛ group: teachers<br/>read-reports ┬╖ own-homework-folder"]
    a["ЁЯкк aishwarya"] --> grp
    s["ЁЯкк katrina"] --> grp
    k["ЁЯкк dipika<br/>no groups"]
    grp -->|"1 policies apply to members"| ok["тЬЕ s3:GetObject report"]
    k -.->|"2 nothing attached"| no["ЁЯЪл IMPLICIT DENY"]

ЁЯЧ║я╕П Drawn version + a lab: https://school-edh.pages.dev/iam/lesson-diagrams.html#l02

тЭУ What

ЁЯдФ Why

Permissions pinned to people drift: someone changes team and keeps the old rights, a leaver keeps a key. Permissions pinned to lists are reviewed once and apply to everyone on them. And a root user in daily use is a master key in a pocket.

ЁЯФз How (in this repo)

In iam/demo.py, GROUPS maps teachers to two policies and MEMBERS says who is on the list; policies_of(name) gathers a user's policies through their groups. users() asks the same question for three people, then adds dipika to the list and asks again.

ЁЯзк Try it

python3 iam/demo.py users
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
groups = {"teachers": ["read-reports", "own-homework-folder"], "exam-board": ["deny-delete-reports"]}
def policies(*gs): return [(p, load(p)) for g in gs for p in groups[g]]
dipika, notes = "arn:aws:iam::111122223333:user/dipika", "arn:aws:s3:::school-homework/dipika/notes.txt"
print("no groups         ", decide(dipika, "s3:PutObject", notes, identity=policies())[0])
print("teachers          ", decide(dipika, "s3:PutObject", notes, identity=policies("teachers"))[0])
print("teachers + exams  ", decide(dipika, "s3:GetObject", "arn:aws:s3:::school-reports/term1.pdf", identity=policies("teachers", "exam-board"))[0])
EOF

On a real account (needs the AWS CLI and credentials):

aws iam create-group --group-name teachers
aws iam create-policy --policy-name read-reports --policy-document file://iam/policies/read-reports.json
aws iam attach-group-policy --group-name teachers --policy-arn arn:aws:iam::111122223333:policy/read-reports
aws iam create-user --user-name dipika
aws iam add-user-to-group --user-name dipika --group-name teachers
aws iam list-groups-for-user --user-name dipika
aws iam get-account-summary --query 'SummaryMap.AccountMFAEnabled'    # 1 = root has MFA

тЬЕ Verify тАФ what you should see

users prints тЬЕ ALLOW for aishwarya and katrina (identity policy read-reports#ReadReports allows it), ЁЯЪл IMPLICIT DENY for dipika with no groups, then тЬЕ ALLOW once dipika joins teachers. Your snippet prints IMPLICIT DENY, ALLOW, ALLOW тАФ joining a second group adds rules; the exam board's Deny is only about s3:DeleteObject, so reading still works.

ЁЯПБ What you just proved

Permissions follow the list: the same person gets or loses access by joining or leaving a group, without anyone editing a policy.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: auditors ask two questions early тАФ "show me the root user's MFA and that it has no keys" and "show me that permissions come from groups or roles, not from individuals". Both are one CLI call to prove.

тПня╕П Next

What exactly is written on a rule? Policies тАФ the four fields every statement has.

git checkout lesson-03-policies
тЖР Previouswhy iamNext тЖТpolicies

This page is the lesson's README from the lesson-02-users-groups-root branch, shown here so the whole School stays on one site. Code files open on GitHub at the same branch.