ЁЯПл The SchoolтА║ЁЯкк IAMтА║ЁЯПв рдзрдбрд╛ 10 тАФ рд▓реЛрдХ рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рд╡рд░: IAM Identity Center
ЁЯЦ╝я╕П See the drawing + lab ЁЯПа Course home ЁЯМ┐ Branch on GitHub тЬПя╕П View source
ЁЯЦ╝я╕П рдЖрдХреГрддреА рдЖрдгрд┐ labThe drawing + lab рдкреВрд░реНрдг рдкрд╛рдирд╛рд╡рд░ рдЙрдШрдбрд╛ тЖЧOpen full page тЖЧ

ЁЯПв рдзрдбрд╛ 10 тАФ рд▓реЛрдХ рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рд╡рд░: IAM Identity Center

ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 10 ┬╖ рдорд╛рдЧреАрд▓: lesson-09-cross-account ┬╖ рдкреБрдвреАрд▓: lesson-11-least-privilege


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

рдзрдбреЗ 01тАУ09, рдЖрдгрд┐ рд▓реЛрдХрд╛рдВрдиреА AWS рдкрд░реНрдпрдВрдд рдХрд╕реЗ рдкреЛрд╣реЛрдЪрд╛рд╡реЗ: IAM Identity Center (рдкреВрд░реНрд╡реАрдЪреЗ AWS SSO) тАФ рдПрдХрдЪ sign-in, рдкреНрд░рддреНрдпреЗрдХ account рдордзреНрдпреЗ roles рдмрдирдгрд╛рд░реЗ permission sets, рдЖрдгрд┐ groups рдкрд╛рд╕реВрди accounts рдкрд░реНрдпрдВрдд assignments. iam/demo.py рдордзреАрд▓ people().

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

рд╢рд╛рд│рд╛рдВрдЪреНрдпрд╛ рд╕рдореВрд╣рд╛рдд рдЖрддрд╛ рджрд╣рд╛ рд╢рд╛рд│рд╛ рдЖрд╣реЗрдд. рдкреНрд░рддреНрдпреЗрдХ рд╢рд┐рдХреНрд╖рд┐рдХреЗрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рд│реЗрдд рд╡реЗрдЧрд│реЗ рдХрд╛рд░реНрдб рджреЗрдгреЗ рдореНрд╣рдгрдЬреЗ рдкреНрд░рддреНрдпреЗрдХреАрд▓рд╛ рджрд╣рд╛ рдХрд╛рд░реНрдбреЗ, рдЖрдгрд┐ рдПрдЦрд╛рджреА рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рд╕реЛрдбреВрди рдЧреЗрд▓реА рдХреА рдХреЛрдгрд╛рд▓рд╛рддрд░реА рддреА рд╕рдЧрд│реА рджрд╣рд╛ рд╢реЛрдзрд╛рд╡реА рд▓рд╛рдЧрддрд╛рдд.

рдореНрд╣рдгреВрди рд╕рдореВрд╣ рдПрдХрдЪ front desk ЁЯПв рдЙрдШрдбрддреЛ. рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рддрд┐рдереЗ рдПрдХрджрд╛рдЪ sign in рдХрд░рддрд╛рдд. Desk рд▓рд╛ рдХрд░реНрдордЪрд╛рд▒реНрдпрд╛рдВрдЪреНрдпрд╛ рдпрд╛рджреНрдпрд╛ (groups) рдЖрдгрд┐ рдПрдХ рддрдХреНрддрд╛ рдорд╛рд╣реАрдд рдЕрд╕рддреЛ: "рд╢рд┐рдХреНрд╖рд┐рдХрд╛рдВрдЪреНрдпрд╛ рдпрд╛рджреАрд▓рд╛ рд╢рд╛рд│рд╛ 1 рдЖрдгрд┐ 2 рдордзреНрдпреЗ Teachers рдЯреЛрдкреА рдорд┐рд│рддреЗ; IT рдпрд╛рджреАрд▓рд╛ рд╕рдЧрд│реАрдХрдбреЗ Admins рдЯреЛрдкреА". Sign in рдХреЗрд▓реНрдпрд╛рд╡рд░ рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рдПрдХ рд╢рд╛рд│рд╛ рдЖрдгрд┐ рдПрдХ рдЯреЛрдкреА рдирд┐рд╡рдбрддреЗ рдЖрдгрд┐ рдЕрд▓реНрдкрдХрд╛рд│рд╛рдЪрд╛ рдкрд╛рд╕ рдШреЗрдКрди рдЖрдд рдЬрд╛рддреЗ.

рдПрдЦрд╛рджреА рд╢рд┐рдХреНрд╖рд┐рдХрд╛ рд╕реЛрдбреВрди рдЧреЗрд▓реА рдХреА desk рддрд┐рдЪреЗ рдирд╛рд╡ рдПрдХрджрд╛рдЪ рдЦреЛрдбрддреЛ тАФ рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╢рд╛рд│реЗрдЪреЗ рджрд╛рд░ рддрд┐рдЪреНрдпрд╛рд╕рд╛рдареА рдЙрдШрдбрдгреЗ рдмрдВрдж рд╣реЛрддреЗ.

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

flowchart LR
    idp["ЁЯСд identity source<br/>Identity Center directory, AD, or Okta / Entra ID"]
    grp["ЁЯУЛ groups<br/>teachers-group ┬╖ it-group"]
    ps["ЁЯОй permission sets<br/>Teachers ┬╖ Admins"]
    acct["ЁЯПл accounts<br/>111122223333 ┬╖ 444455556666"]
    role["AWSReservedSSO_Teachers_тАж<br/>a role in each assigned account"]
    idp --> grp -->|"1 assignment"| ps -->|"2 provisioned into"| acct --> role
    role -->|"3 sign in, get temporary credentials"| ok["тЬЕ s3:GetObject"]

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

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

ЁЯдФ рдХрд╛

рдХрд╛рд░рдг рд▓реЛрдХ teams рдмрджрд▓рддрд╛рдд рдЖрдгрд┐ рд╕реЛрдбреВрди рдЬрд╛рддрд╛рдд, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ account рдордзрд▓рд╛ password рдЖрдгрд┐ keys рдЕрд╕рд▓реЗрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ IAM user рдореНрд╣рдгрдЬреЗ рд╡рд┐рд╕рд░рдгреНрдпрд╛рд╕рд╛рд░рдЦреА рдЖрдгрдЦреА рдПрдХ рдЧреЛрд╖реНрдЯ. рдПрдХ identity, рдЕрд▓реНрдкрдХрд╛рд│рд╛рдЪреЗ role sessions, accounts рд╢реА рдЬреЛрдбрд▓реЗрд▓реЗ groups: рдпреЗрдгреЗ, рдмрджрд▓рдгреЗ рдЖрдгрд┐ рдЬрд╛рдгреЗ тАФ рдкреНрд░рддреНрдпреЗрдХреА рдПрдХрдЪ рдмрджрд▓ рд╣реЛрддреЛ.

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

iam/demo.py рдордзреАрд▓ people() рджреЛрди groups рдирд╛ рджреЛрди permission sets рд╢реА рдЬреЛрдбрддреЗ рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ assignment рдХреЛрдгрддрд╛ role рдмрдирд╡рддреЗ рддреЗ рдЫрд╛рдкрддреЗ, рдордЧ Teachers permission set рдЪреНрдпрд╛ policy (read-reports) рд╕рд╣ рдПрдХрд╛ SSO session ARN рдЪреЗ рдореВрд▓реНрдпрдорд╛рдкрди рдХрд░рддреЗ: report рд╡рд╛рдЪрддрд╛ рдпреЗрддреЛ, EC2 terminate рдХрд░рддрд╛ рдпреЗрдд рдирд╛рд╣реА.

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

python3 iam/demo.py people
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
permission_sets = {"Teachers": [("read-reports", load("read-reports"))], "Admins": [("admin", load("admin"))]}
assignments = {"teachers-group": "Teachers", "it-group": "Admins"}
members = {"aishwarya@school.example": ["teachers-group"], "meera@school.example": ["it-group"]}
def sign_in(email, permission_set, action="ec2:TerminateInstances"):
    if permission_set not in [assignments[g] for g in members.get(email, [])]:
        return "no assignment, no role to assume"
    session = "arn:aws:sts::111122223333:assumed-role/AWSReservedSSO_" + permission_set + "_1a2b/" + email
    return decide(session, action, "*", identity=permission_sets[permission_set])[0]
print("aishwarya as Teachers:", sign_in("aishwarya@school.example", "Teachers"))
print("aishwarya as Admins:  ", sign_in("aishwarya@school.example", "Admins"))
print("meera as Admins:      ", sign_in("meera@school.example", "Admins"))
members["meera@school.example"] = []          # meera leaves: removed once, in the identity source
print("meera, after:         ", sign_in("meera@school.example", "Admins"))
EOF

рдЦрд▒реНрдпрд╛ account рд╡рд░ (AWS CLI рдЖрдгрд┐ Identity Center instance рд▓рд╛рдЧрддреЛ; instance, permission set рдЖрдгрд┐ group IDs рдЙрджрд╛рд╣рд░рдгрд╛рджрд╛рдЦрд▓ рдЖрд╣реЗрдд):

aws configure sso                                           # asks for the start URL, region, account and permission set
aws sso login --profile school-teachers
aws sts get-caller-identity --profile school-teachers
aws sso-admin create-permission-set --instance-arn arn:aws:sso:::instance/ssoins-1111222233334444 --name Teachers --session-duration PT4H
aws sso-admin create-account-assignment --instance-arn arn:aws:sso:::instance/ssoins-1111222233334444 --target-id 111122223333 --target-type AWS_ACCOUNT --permission-set-arn arn:aws:sso:::permissionSet/ssoins-1111222233334444/ps-1111222233334444 --principal-type GROUP --principal-id a1b2c3d4-5678-90ab-cdef-EXAMPLE11111

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

people рддреАрди ЁЯСе рдУрд│реА рдЫрд╛рдкрддреЗ (teachers-group тЖТ рдПрдХрд╛ account рдордзреНрдпреЗ Teachers; it-group тЖТ рджреЛрдиреНрд╣реАрдордзреНрдпреЗ Admins), рдордЧ тЬЕ aishwarya via SSO (Teachers) тЖТ read a report ALLOW рдЖрдгрд┐ ЁЯЪл aishwarya via SSO (Teachers) тЖТ terminate EC2 IMPLICIT DENY. рддреБрдордЪрд╛ snippet рдЫрд╛рдкрддреЛ IMPLICIT DENY (Teachers terminate рдХрд░реВ рд╢рдХрдд рдирд╛рд╣реА), no assignment, no role to assume (aishwarya рд▓рд╛ Admins assignment рдирд╛рд╣реА), meera рд╕рд╛рдареА ALLOW, рдЖрдгрд┐ рддреА рд╕реЛрдбреВрди рдЧреЗрд▓реНрдпрд╛рд╡рд░ no assignment, no role to assume. рдЦрд▒реНрдпрд╛ account рд╡рд░ get-caller-identity рдЕрд╕рд╛ Arn рджрд╛рдЦрд╡рддреЛ рдЬреНрдпрд╛рдд assumed-role/AWSReservedSSO_ рдЕрд╕рддреЗ.

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

рд▓реЛрдХрд╛рдВрдирд╛ group тЖТ permission set тЖТ account assignments рдорд╛рд░реНрдЧреЗ, рдЕрд▓реНрдкрдХрд╛рд│рд╛рдЪреНрдпрд╛ role sessions рдЪреНрдпрд╛ рд░реВрдкрд╛рдд access рдорд┐рд│рддреЛ тАФ рдЖрдгрд┐ рдПрдЦрд╛рджреНрдпрд╛рд▓рд╛ рдПрдХрджрд╛ рдХрд╛рдврд▓реЗ рдХреА рддреА рд╕рдЧрд│реАрдХрдбреВрди рдирд┐рдШрддреЗ.

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

ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: joiner-mover-leaver рд╣реЗ рдПрдХ audit control рдЖрд╣реЗ. Identity Center рдХрдВрдкрдиреАрдЪреНрдпрд╛ directory рд╢реА рдЬреЛрдбрд▓реЗрд▓реЗ рдЕрд╕реЗрд▓ рддрд░ HR рдЪрд╛ "leaver" event рдХрд╛рд╣реА рдорд┐рдирд┐рдЯрд╛рдВрдд AWS access рдХрд╛рдвреВрди рдЯрд╛рдХрддреЛ тАФ рдЖрдгрд┐ credential report рдордзреНрдпреЗ рдПрдХрд╣реА рдорд╛рдирд╡реА IAM user рджрд┐рд╕рдд рдирд╛рд╣реА.

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

рдкреНрд░рддреНрдпреЗрдХрд╛рд▓рд╛ рдпреЛрдЧреНрдп рджрд╛рд░рд╛рддреВрди access рдЖрд╣реЗ тАФ рдкрдг рддреНрдпрд╛рдВрдЪреНрдпрд╛рдХрдбреЗ рдЬрд╛рд╕реНрдд рддрд░ рдирд╛рд╣реА рдирд╛? Least privilege, рдЕрдВрджрд╛рдЬрд╛рдиреЗ рдирд╡реНрд╣реЗ рддрд░ рдореЛрдЬреВрди.

git checkout lesson-11-least-privilege

ЁЯПв Lesson 10 тАФ People at scale: IAM Identity Center

ЁЯУН You are here: Lesson 10 of 12 ┬╖ Previous: lesson-09-cross-account ┬╖ Next: lesson-11-least-privilege


ЁЯУж What's in this branch

Lessons 01тАУ09, plus how people should reach AWS: IAM Identity Center (formerly AWS SSO) тАФ one sign-in, permission sets that become roles in each account, and assignments from groups to accounts. people() in iam/demo.py.

ЁЯзТ Explain like I'm 5

The school group now has ten schools. Giving every teacher a separate card at every school means ten cards each, and when a teacher leaves, someone must find all ten.

So the group opens one front desk ЁЯПв. Teachers sign in there once. The desk knows the staff lists (groups) and a chart: "the teachers list gets the Teachers hat at schools 1 and 2; the IT list gets the Admins hat everywhere". After signing in, a teacher picks a school and a hat and walks in with a short-lived pass.

When a teacher leaves, the desk crosses them off once тАФ and every school's door stops opening for them.

ЁЯЧ║я╕П Diagram

flowchart LR
    idp["ЁЯСд identity source<br/>Identity Center directory, AD, or Okta / Entra ID"]
    grp["ЁЯУЛ groups<br/>teachers-group ┬╖ it-group"]
    ps["ЁЯОй permission sets<br/>Teachers ┬╖ Admins"]
    acct["ЁЯПл accounts<br/>111122223333 ┬╖ 444455556666"]
    role["AWSReservedSSO_Teachers_тАж<br/>a role in each assigned account"]
    idp --> grp -->|"1 assignment"| ps -->|"2 provisioned into"| acct --> role
    role -->|"3 sign in, get temporary credentials"| ok["тЬЕ s3:GetObject"]

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

тЭУ What

ЁЯдФ Why

Because people change teams and leave, and every IAM user with a password and keys in every account is one more thing to forget. One identity, short-lived role sessions, groups mapped to accounts: joining, moving and leaving become one change each.

ЁЯФз How (in this repo)

people() in iam/demo.py maps two groups to two permission sets and prints the role each assignment creates, then evaluates an SSO session ARN with the Teachers permission set's policy (read-reports): reading a report works, terminating EC2 does not.

ЁЯзк Try it

python3 iam/demo.py people
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
permission_sets = {"Teachers": [("read-reports", load("read-reports"))], "Admins": [("admin", load("admin"))]}
assignments = {"teachers-group": "Teachers", "it-group": "Admins"}
members = {"aishwarya@school.example": ["teachers-group"], "meera@school.example": ["it-group"]}
def sign_in(email, permission_set, action="ec2:TerminateInstances"):
    if permission_set not in [assignments[g] for g in members.get(email, [])]:
        return "no assignment, no role to assume"
    session = "arn:aws:sts::111122223333:assumed-role/AWSReservedSSO_" + permission_set + "_1a2b/" + email
    return decide(session, action, "*", identity=permission_sets[permission_set])[0]
print("aishwarya as Teachers:", sign_in("aishwarya@school.example", "Teachers"))
print("aishwarya as Admins:  ", sign_in("aishwarya@school.example", "Admins"))
print("meera as Admins:      ", sign_in("meera@school.example", "Admins"))
members["meera@school.example"] = []          # meera leaves: removed once, in the identity source
print("meera, after:         ", sign_in("meera@school.example", "Admins"))
EOF

On a real account (needs the AWS CLI and an Identity Center instance; the instance, permission set and group IDs are examples):

aws configure sso                                           # asks for the start URL, region, account and permission set
aws sso login --profile school-teachers
aws sts get-caller-identity --profile school-teachers
aws sso-admin create-permission-set --instance-arn arn:aws:sso:::instance/ssoins-1111222233334444 --name Teachers --session-duration PT4H
aws sso-admin create-account-assignment --instance-arn arn:aws:sso:::instance/ssoins-1111222233334444 --target-id 111122223333 --target-type AWS_ACCOUNT --permission-set-arn arn:aws:sso:::permissionSet/ssoins-1111222233334444/ps-1111222233334444 --principal-type GROUP --principal-id a1b2c3d4-5678-90ab-cdef-EXAMPLE11111

тЬЕ Verify тАФ what you should see

people prints three ЁЯСе lines (teachers-group тЖТ Teachers in one account; it-group тЖТ Admins in both), then тЬЕ aishwarya via SSO (Teachers) тЖТ read a report ALLOW and ЁЯЪл aishwarya via SSO (Teachers) тЖТ terminate EC2 IMPLICIT DENY. Your snippet prints IMPLICIT DENY (Teachers cannot terminate), no assignment, no role to assume (aishwarya has no Admins assignment), ALLOW for meera, and after she leaves, no assignment, no role to assume. On a real account, get-caller-identity shows an Arn containing assumed-role/AWSReservedSSO_.

ЁЯПБ What you just proved

People get access through group тЖТ permission set тЖТ account assignments, as short-lived role sessions тАФ and removing someone once removes them everywhere.

тЪая╕П Common mistakes

ЁЯПн Why this matters in production: joiner-mover-leaver is an audit control. With Identity Center connected to the company directory, HR's "leaver" event removes AWS access within minutes тАФ and the credential report shows no human IAM users at all.

тПня╕П Next

Everyone has access through the right door тАФ but do they have too much? Least privilege, measured instead of guessed.

git checkout lesson-11-least-privilege
тЖР Previouscross accountNext тЖТleast privilege

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