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

ЁЯП╖я╕П рдзрдбрд╛ 07 тАФ Conditions рдЖрдгрд┐ ABAC: "рдлрдХреНрдд рддреЗрд╡реНрд╣рд╛рдЪтАж"

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 07 ┬╖ рдорд╛рдЧреЗ: lesson-06-machine-identities ┬╖ рдкреБрдвреЗ: lesson-08-guardrails


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

рдзрдбреЗ 01тАУ06, рдЖрдгрд┐ рддреНрдпрд╛рд╕реЛрдмрдд Condition block: IAM рдмрджрд▓рд╛рдВрд╕рд╛рдареА MFA рдмрдВрдзрдирдХрд╛рд░рдХ (iam-needs-mfa.json), рдлрдХреНрдд рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдЪреЗ network (office-network-only.json), рдЖрдгрд┐ ABAC тАФ tags рд╡рд░реВрди рдард░рдгрд╛рд░рд╛ access (abac-own-team.json).

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

рдХрд╛рд╣реА рдирд┐рдпрдорд╛рдВрдЪреНрдпрд╛ рд╢реЗрд╡рдЯреА "рдлрдХреНрдд рддреЗрд╡реНрд╣рд╛рдЪтАж" рдЕрд╕рддреЗ:

рд╢реЗрд╡рдЯрдЪрд╛ рдирд┐рдпрдо рд╕рдЧрд│реНрдпрд╛рдд рд╣реБрд╢рд╛рд░ рдЖрд╣реЗ. рдкреНрд░рддреНрдпреЗрдХ team рд╕рд╛рдареА рд╡реЗрдЧрд│рд╛ рдирд┐рдпрдо рдирд╛рд╣реА, рддрд░ рдПрдХрдЪ рдирд┐рдпрдо рдЕрд╕рддреЛ тАФ "stickers рдЬреБрд│рд╛рдпрд▓рд╛ рд╣рд╡реЗрдд" тАФ рдЖрдгрд┐ рдирд╡реНрдпрд╛ team рд▓рд╛ рдлрдХреНрдд sticker рдЪрд╛ рдирд╡рд╛ рд░рдВрдЧ рд▓рд╛рдЧрддреЛ.

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

flowchart LR
    me["ЁЯкк aishwarya<br/>PrincipalTag team = maths"]
    rule["ЁЯУЭ abac-own-team<br/>StringEquals<br/>ResourceTag/team = PrincipalTag/team"]
    m["ЁЯЦея╕П instance ┬╖ team = maths"]
    s["ЁЯЦея╕П instance ┬╖ team = science"]
    me --> rule
    rule -->|"1 tags match"| m --> ok["тЬЕ ALLOW StopInstances"]
    rule -->|"2 tags differ"| s --> no["ЁЯЪл IMPLICIT DENY"]

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

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

ЁЯдФ рдХрд╛

рддреБрдореНрд╣реА рдХреЛрдг рдЖрд╣рд╛рдд рдПрд╡рдвреЗ рдиреЗрд╣рдореАрдЪ рдкреБрд░реЗрд╕реЗ рдирд╕рддреЗ; рддреБрдореНрд╣реА рдХрд╕реЗ рдЖрдгрд┐ рдХреБрдареВрди рд╡рд┐рдЪрд╛рд░рддрд╛ рд╣реЗрд╣реА рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ рдЕрд╕рддреЗ. Conditions рдзреЛрдХрд╛рджрд╛рдпрдХ actions рд╕рдореЛрд░ MFA рдареЗрд╡рддрд╛рдд рдЖрдгрд┐ data рдЕрдкреЗрдХреНрд╖рд┐рдд networks рдЪреНрдпрд╛ рдЖрддрдЪ рдареЗрд╡рддрд╛рдд. ABAC policies рдЪрд╛ рдкрд╕рд╛рд░рд╛ рдерд╛рдВрдмрд╡рддреЗ: рджрд╣рд╛ teams, рдПрдХрдЪ policy.

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

iam/demo.py рдордзрд▓рд╛ conditions() рдПрдХ request context рджреЗрддреЛ (decide() рдЪрд╛ рддрд┐рд╕рд░рд╛ argument, condition keys рдЪреА dict) тАФ MFA true/false, рджреЛрди source IPs, рдЖрдгрд┐ principal/resource tags. iam/evaluate.py рдордзрд▓рд╛ _condition_ok() operators, тАжIfExists, рдЖрдгрд┐ рдирд╕рд▓реЗрд▓реНрдпрд╛ key рдЪрд╛ рдирд┐рдпрдо рдЕрдорд▓рд╛рдд рдЖрдгрддреЛ.

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

python3 iam/demo.py conditions
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
aishwarya = "arn:aws:iam::111122223333:user/aishwarya"
print("MFA key absent      ", decide(aishwarya, "iam:CreateUser", "*", {}, identity=[("iam-needs-mfa", load("iam-needs-mfa"))]))
abac = [("abac-own-team", load("abac-own-team"))]
inst = "arn:aws:ec2:ap-south-1:111122223333:instance/i-0abc"
print("no team tag on me   ", decide(aishwarya, "ec2:StopInstances", inst, {"aws:ResourceTag/team": "maths"}, identity=abac)[0])
print("science = science   ", decide(aishwarya, "ec2:StopInstances", inst, {"aws:PrincipalTag/team": "science", "aws:ResourceTag/team": "science"}, identity=abac)[0])
print("other region        ", decide(aishwarya, "ec2:StopInstances", "arn:aws:ec2:us-east-1:111122223333:instance/i-0abc", {"aws:PrincipalTag/team": "maths", "aws:ResourceTag/team": "maths"}, identity=abac)[0])
EOF

рдЦрд▒реНрдпрд╛ account рд╡рд░ (AWS CLI рдЖрдгрд┐ credentials рд▓рд╛рдЧрддрд╛рдд) тАФ рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдирд╛ tags рд▓рд╛рд╡рд╛, рдЖрдгрд┐ CLI рд╕рд╛рдареА MFA рдЪрд╛ рдЖрдзрд╛рд░ рдЕрд╕рд▓реЗрд▓реА рддрд╛рддреНрдкреБрд░рддреА credentials рдорд┐рд│рд╡рд╛:

aws iam tag-user --user-name aishwarya --tags Key=team,Value=maths
aws ec2 create-tags --resources i-0abc1234def567890 --tags Key=team,Value=maths
aws sts get-session-token --serial-number arn:aws:iam::111122223333:mfa/aishwarya --token-code 123456

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

conditions MFA рд╕рд╛рдареА рдЖрдзреА ЁЯЪл IMPLICIT DENY рдЖрдгрд┐ рдордЧ тЬЕ ALLOW тАФ identity policy iam-needs-mfa#IamOnlyWithMfa allows it print рдХрд░рддреЛ; рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рддреВрди тЬЕ ALLOW рдЖрдгрд┐ caf├й рдордзреВрди тЫФ DENY тАФ explicit Deny in identity policy office-network-only#DenyOutsideOffice; maths-on-maths рд╕рд╛рдареА тЬЕ ALLOW рдЖрдгрд┐ maths-on-science рд╕рд╛рдареА ЁЯЪл IMPLICIT DENY. рддреБрдордЪрд╛ snippet ('IMPLICIT DENY', 'no policy allows it тАФ AWS denies by default') (request рдордзреНрдпреЗ MFA key рдирд╛рд╣реА), IMPLICIT DENY (aishwarya рд╡рд░ team tag рдирд╛рд╣реА тАФ variable рд▓рд╛ рднрд░рд╛рдпрд▓рд╛ рдХрд╛рд╣реАрдЪ рдирд╛рд╣реА), ALLOW (science рд▓рд╛ science рдЬреБрд│рддреЗ: рддреАрдЪ policy, рд╡реЗрдЧрд│реА team) рдЖрдгрд┐ IMPLICIT DENY (policy рдЪрд╛ Resource рдлрдХреНрдд ap-south-1 рд▓рд╛рдЪ рд▓рд╛рдЧреВ рд╣реЛрддреЛ) print рдХрд░рддреЛ.

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

Conditions рдореБрд│реЗ рддреНрдпрд╛рдЪ principal рд▓рд╛ MFA, network рдЖрдгрд┐ tags рдиреБрд╕рд╛рд░ рд╡реЗрдЧрд╡реЗрдЧрд│реА рдЙрддреНрддрд░реЗ рдорд┐рд│рддрд╛рдд тАФ рдЖрдгрд┐ ABAC рдореБрд│реЗ рдПрдХрдЪ policy рдкреНрд░рддреНрдпреЗрдХ team рд▓рд╛ рдЪрд╛рд▓рддреЗ.

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

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: "рдкреНрд░рддреНрдпреЗрдХ рд╕рдВрд╡реЗрджрдирд╢реАрд▓ рдЧреЛрд╖реНрдЯреАрд╕рд╛рдареА MFA", "data рдлрдХреНрдд рдЖрдордЪреНрдпрд╛ network рдордзреВрди рдХрд┐рдВрд╡рд╛ рдЖрдордЪреНрдпрд╛ organization рдордзреВрди (aws:PrincipalOrgID)" рдЖрдгрд┐ "teams рдлрдХреНрдд рддреНрдпрд╛рдВрдиреА tag рдХреЗрд▓реЗрд▓реЗрдЪ рд╕рд╛рдВрднрд╛рд│рддрд╛рдд" рдпрд╛ enterprise IAM рдордзрд▓реНрдпрд╛ рд╕рдЧрд│реНрдпрд╛рдд рдиреЗрд╣рдореАрдЪреНрдпрд╛ рддреАрди рдЧрд░рдЬрд╛ рдЖрд╣реЗрдд тАФ рдЖрдгрд┐ рддрд┐рдиреНрд╣реА conditions рдЪ.

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

Admin рдЕрдзрд┐рдХрд╛рд░ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ рд╡реНрдпрдХреНрддреАрд▓рд╛рд╣реА рд╕рдЧрд│реЗ рдХрд░рддрд╛ рдпреЗрдК рдирдпреЗ. Guardrails тАФ permission boundaries рдЖрдгрд┐ SCPs, рдкреНрд░рддреНрдпреЗрдХ policy рд╡рд░рдЪреА рдЫрддреЗ.

git checkout lesson-08-guardrails

ЁЯП╖я╕П Lesson 07 тАФ Conditions & ABAC: "only whenтАж"

ЁЯУН You are here: Lesson 07 of 12 ┬╖ Previous: lesson-06-machine-identities ┬╖ Next: lesson-08-guardrails


ЁЯУж What's in this branch

Lessons 01тАУ06, plus the Condition block: MFA required for IAM changes (iam-needs-mfa.json), office network only (office-network-only.json), and ABAC тАФ access decided by tags (abac-own-team.json).

ЁЯзТ Explain like I'm 5

Some rules have an "only whenтАж" at the end:

The last one is the clever one. Instead of a rule per team, there is one rule тАФ "stickers must match" тАФ and a new team only needs a new colour of sticker.

ЁЯЧ║я╕П Diagram

flowchart LR
    me["ЁЯкк aishwarya<br/>PrincipalTag team = maths"]
    rule["ЁЯУЭ abac-own-team<br/>StringEquals<br/>ResourceTag/team = PrincipalTag/team"]
    m["ЁЯЦея╕П instance ┬╖ team = maths"]
    s["ЁЯЦея╕П instance ┬╖ team = science"]
    me --> rule
    rule -->|"1 tags match"| m --> ok["тЬЕ ALLOW StopInstances"]
    rule -->|"2 tags differ"| s --> no["ЁЯЪл IMPLICIT DENY"]

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

тЭУ What

ЁЯдФ Why

Who you are is not always enough; how and from where you ask matters too. Conditions put MFA in front of dangerous actions and keep data inside expected networks. ABAC stops policy sprawl: ten teams, one policy.

ЁЯФз How (in this repo)

conditions() in iam/demo.py passes a request context (the third argument of decide(), a dict of condition keys) тАФ MFA true/false, two source IPs, and principal/resource tags. _condition_ok() in iam/evaluate.py implements the operators, тАжIfExists, and the missing-key rule.

ЁЯзк Try it

python3 iam/demo.py conditions
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
aishwarya = "arn:aws:iam::111122223333:user/aishwarya"
print("MFA key absent      ", decide(aishwarya, "iam:CreateUser", "*", {}, identity=[("iam-needs-mfa", load("iam-needs-mfa"))]))
abac = [("abac-own-team", load("abac-own-team"))]
inst = "arn:aws:ec2:ap-south-1:111122223333:instance/i-0abc"
print("no team tag on me   ", decide(aishwarya, "ec2:StopInstances", inst, {"aws:ResourceTag/team": "maths"}, identity=abac)[0])
print("science = science   ", decide(aishwarya, "ec2:StopInstances", inst, {"aws:PrincipalTag/team": "science", "aws:ResourceTag/team": "science"}, identity=abac)[0])
print("other region        ", decide(aishwarya, "ec2:StopInstances", "arn:aws:ec2:us-east-1:111122223333:instance/i-0abc", {"aws:PrincipalTag/team": "maths", "aws:ResourceTag/team": "maths"}, identity=abac)[0])
EOF

On a real account (needs the AWS CLI and credentials) тАФ tag both sides, and get MFA-backed temporary credentials for the CLI:

aws iam tag-user --user-name aishwarya --tags Key=team,Value=maths
aws ec2 create-tags --resources i-0abc1234def567890 --tags Key=team,Value=maths
aws sts get-session-token --serial-number arn:aws:iam::111122223333:mfa/aishwarya --token-code 123456

тЬЕ Verify тАФ what you should see

conditions prints ЁЯЪл IMPLICIT DENY then тЬЕ ALLOW тАФ identity policy iam-needs-mfa#IamOnlyWithMfa allows it for MFA; тЬЕ ALLOW from the office and тЫФ DENY тАФ explicit Deny in identity policy office-network-only#DenyOutsideOffice from the caf├й; тЬЕ ALLOW for maths-on-maths and ЁЯЪл IMPLICIT DENY for maths-on-science. Your snippet prints ('IMPLICIT DENY', 'no policy allows it тАФ AWS denies by default') (no MFA key in the request), IMPLICIT DENY (no team tag on aishwarya тАФ the variable has nothing to fill in), ALLOW (science matches science: same policy, different team) and IMPLICIT DENY (the policy's Resource only covers ap-south-1).

ЁЯПБ What you just proved

Conditions make the same principal get different answers depending on MFA, network and tags тАФ and ABAC lets one policy serve every team.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: "MFA for anything sensitive", "data only from our network or our organization (aws:PrincipalOrgID)" and "teams manage only what they tag" are three of the most common enterprise IAM requirements тАФ all conditions.

тПня╕П Next

Someone with admin rights still should not be able to do everything. Guardrails тАФ permission boundaries and SCPs, the ceilings above every policy.

git checkout lesson-08-guardrails
тЖР Previousmachine identitiesNext тЖТguardrails

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