ЁЯдЭ рдзрдбрд╛ 09 тАФ Cross-account рдЖрдгрд┐ resource policies: рджреЛрди рджрд░рд╡рд╛рдЬреЗ, рджреЛрди рдЪрд╛рд╡реНрдпрд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 09 ┬╖ рдорд╛рдЧреАрд▓: lesson-08-guardrails ┬╖ рдкреБрдвреАрд▓: lesson-10-people-at-scale
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ08, рдЖрдгрд┐ resource-based policies тАФ рд╡рд╕реНрддреВрд╡рд░рдЪ рдЕрд╕рд▓реЗрд▓реА policy (S3
bucket policy, bucket-policy-reports.json)
рдЬреА Principal рдиреЗ рдХреЛрдг рддреЗ рд╕рд╛рдВрдЧрддреЗ тАФ рдЖрдгрд┐ cross-account access, рдЬрд┐рдереЗ partner
account рдЪрд╛ role (partner-auditor-identity.json)
рд╢рд╛рд│реЗрдЪреЗ reports рд╡рд╛рдЪрддреЛ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
Partner рд╢рд╛рд│реЗрдЪреНрдпрд╛ auditor рд▓рд╛ рддреБрдордЪреА рдкреНрд░рдЧрддрд┐рдкреБрд╕реНрддрдХреЗ рд╡рд╛рдЪрд╛рдпрдЪреА рдЖрд╣реЗрдд. рджреЛрди рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдВрдиреА рдорд╛рдиреНрдп рдХрд░рд╛рдпрд▓рд╛ рд╣рд╡реЗ:
- рддрд┐рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ рд╢рд╛рд│реЗрдЪреНрдпрд╛ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдиреЗ рдореНрд╣рдгрд╛рдпрд▓рд╛ рд╣рд╡реЗ "рд╣реЛ, рдЖрдордЪреА auditor рдЗрддрд░ рд╢рд╛рд│рд╛рдВрдЪреЗ reports рд╡рд╛рдЪреВ рд╢рдХрддреЗ" (рддрд┐рдЪреА identity policy).
- рддреБрдордЪреНрдпрд╛ рд╢рд╛рд│реЗрдЪреНрдпрд╛ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдиреЗ рдореНрд╣рдгрд╛рдпрд▓рд╛ рд╣рд╡реЗ "рд╣реЛ, рддреА auditor рдЖрдордЪреЗ reports рд╡рд╛рдЪреВ рд╢рдХрддреЗ" тАФ reports рдЪреНрдпрд╛ рдХрдкрд╛рдЯрд╛рд╡рд░рдЪ рд▓рд╛рд╡рд▓реЗрд▓реА рдЪрд┐рдареНрдареА (bucket policy).
рджреЛрди рджрд░рд╡рд╛рдЬреЗ ЁЯЪкЁЯЪк, рджреЛрди рдЪрд╛рд╡реНрдпрд╛ ЁЯФСЁЯФС. рдПрдХрд╛рдЪ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рдиреЗ рд╣реЛ рдореНрд╣рдЯрд▓реЗ рддрд░ рддреА рдмрд╛рд╣реЗрд░рдЪ рд░рд╛рд╣рддреЗ. рдПрдХрд╛рдЪ рд╢рд╛рд│реЗрдд рд╣реЗ рд╕реЛрдкреЗ рдЕрд╕рддреЗ: рдХрдкрд╛рдЯрд╛рд╡рд░рдЪреА, рдПрдЦрд╛рджреНрдпрд╛ рд╢рд┐рдХреНрд╖рд┐рдХреЗрдЪреЗ рдирд╛рд╡ рдЕрд╕рд▓реЗрд▓реА рдЪрд┐рдареНрдареА рдПрдХрдЯреАрдЪ рдкреБрд░реЗрд╢реА рдЕрд╕рддреЗ.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
aud["ЁЯХ╡я╕П role/partner-auditor<br/>account 444455556666"]
idp["ЁЯУЭ her identity policy<br/>s3:GetObject school-reports/*"]
bp["ЁЯУМ bucket policy on school-reports<br/>Principal: role/partner-auditor"]
obj["ЁЯУД school-reports/term1.pdf<br/>account 111122223333"]
aud -->|"1 her account says yes"| idp
idp -->|"2 the bucket says yes"| bp
bp -->|"both"| obj
obj --> ok["тЬЕ ALLOW"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрдХреГрддреА + рдПрдХ lab: https://school-edh.pages.dev/iam/lesson-diagrams.html#l09
тЭУ рдХрд╛рдп
- Resource-based policy тАФ resource рд▓рд╛ рдЬреЛрдбрд▓реЗрд▓реА: S3 bucket policies, KMS key
policies, SQS queue рдЖрдгрд┐ SNS topic policies, Lambda function policies, ECR repository
policies, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ role рдЪреА trust policy. рддрд┐рдЪреНрдпрд╛рдд
PrincipalрдЕрд╕рддреЛ. - рддреНрдпрд╛рдЪ account рдордзреНрдпреЗ тАФ identity policy рдХрд┐рдВрд╡рд╛ resource policy, рдпрд╛рдВрдкреИрдХреА рдПрдХрд╛рдиреЗ allow рдХреЗрд▓реЗ рддрд░реА рдкреБрд░реЗрд╕реЗ (рдЬреЛрдкрд░реНрдпрдВрдд рдХрд╛рд╣реАрддрд░реА deny рдХрд░рдд рдирд╛рд╣реА).
- Cross-account тАФ рджреЛрдШрд╛рдВрдиреА allow рдХрд░рд╛рдпрд▓рд╛ рд╣рд╡реЗ: caller рдЪреЗ account (identity policy, рдЖрдгрд┐ рддреНрдпрд╛рдЪреНрдпрд╛ boundaries рд╡ SCPs) рдЖрдгрд┐ рджреБрд╕рд▒реНрдпрд╛ account рдордзреАрд▓ resource policy.
- Principal рдЪреЗ рдкреНрд░рдХрд╛рд░ тАФ role рдХрд┐рдВрд╡рд╛ user ARN (рдиреЗрдордХрд╛ рддреЛрдЪ), рдХрд┐рдВрд╡рд╛
arn:aws:iam::444455556666:root, рдЬреНрдпрд╛рдЪрд╛ рдЕрд░реНрде рддреЗ account тАФ "рддреНрдпрд╛ account рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ policies рдЬреНрдпрд╛рд▓рд╛ allow рдХрд░рддрд╛рдд рддреЛ рдХреЛрдгреАрд╣реА" тАФ рддреНрдпрд╛рдЪрд╛ root user рдирд╡реНрд╣реЗ. - рдкрд▓реАрдХрдбреЗ рдЬрд╛рдгреНрдпрд╛рдЪреЗ рджреЛрди рдорд╛рд░реНрдЧ тАФ рджреБрд╕рд▒реНрдпрд╛ account рдЪреЗ рдирд╛рд╡ рдШреЗрдгрд╛рд░реА resource policy (рд╣рд╛ рдзрдбрд╛),
рдХрд┐рдВрд╡рд╛ рддреБрдордЪреНрдпрд╛ account рдордзреАрд▓ рдПрдХ role рдЬреЛ partner assume рдХрд░рддреЛ (trust policy + рддреНрдпрд╛рдВрдЪреА
sts:AssumeRolepermission). Roles рдкреНрд░рддреНрдпреЗрдХ service рд╕рд╛рдареА рдЪрд╛рд▓рддрд╛рдд; resource policies рдлрдХреНрдд рддреНрдпрд╛ рдЕрд╕рд▓реЗрд▓реНрдпрд╛ services рд╕рд╛рдареА. - Confused deputy тАФ рдЬреЗрд╡реНрд╣рд╛ рдПрдЦрд╛рджрд╛ third party рддреБрдордЪрд╛ role assume рдХрд░рддреЛ, рддреЗрд╡реНрд╣рд╛
sts:ExternalIdрдЖрд╡рд╢реНрдпрдХ рдХрд░рд╛; AWS service principals рд╕рд╛рдареАaws:SourceArn/aws:SourceAccountрддрдкрд╛рд╕рд╛. - Encryption рд╣рд╛ рддрд┐рд╕рд░рд╛ рджрд░рд╡рд╛рдЬрд╛ рдЖрд╣реЗ тАФ customer managed KMS key рдЦрд╛рд▓реАрд▓ objects рд╕рд╛рдареА key policy рдиреЗрд╣реА
partner рд▓рд╛ allow рдХрд░рд╛рдпрд▓рд╛ рд╣рд╡реЗ (
kms:Decrypt).
ЁЯдФ рдХрд╛
рдЦрд▒реНрдпрд╛ organizations рдХрдбреЗ рдЕрдиреЗрдХ accounts рдЕрд╕рддрд╛рдд (рдкреНрд░рддреНрдпреЗрдХ team рд╕рд╛рдареА, рдкреНрд░рддреНрдпреЗрдХ environment рд╕рд╛рдареА), рд╢рд┐рд╡рд╛рдп partners рдЖрдгрд┐
vendors. Cross-account access рдореБрд│реЗ рддреЗ credentials рди рджреЗрддрд╛ share рдХрд░реВ рд╢рдХрддрд╛рдд тАФ рдЖрдгрд┐ рдЪреБрдХреАрдЪреА рд╡рд╛рдЪрд▓реЗрд▓реА
bucket policy ("Principal": "*") рд╣реА public-data рдЧрд│рддреАрдЪреЗ рдХреНрд▓рд╛рд╕рд┐рдХ рдЙрджрд╛рд╣рд░рдг рдЖрд╣реЗ.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
iam/demo.py рдордзреАрд▓ crossaccount() partner auditor рд╕рд╛рдареА decide() рд▓рд╛
resource_policy= рдЖрдгрд┐ resource_account= (рд╢рд╛рд│реЗрдЪреЗ account) рджреЗрдКрди рдмреЛрд▓рд╛рд╡рддреЗ: рджреЛрдиреНрд╣реА рдмрд╛рдЬреВ,
рдлрдХреНрдд bucket, рдлрдХреНрдд identity, рдЖрдгрд┐ рдПрдХ delete. iam/evaluate.py рдордзреАрд▓
_principal_ok() resource policy рдЪрд╛ Principal рддрдкрд╛рд╕рддреЗ, account рдкреНрд░рдХрд╛рд░ тАж:root рд╕рдХрдЯ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 iam/demo.py crossaccount
python3 - <<'EOF'
import sys; sys.path.insert(0, "iam"); from evaluate import decide, load
R, SCHOOL = "arn:aws:s3:::school-reports/term1.pdf", "111122223333"
ident = [("partner-auditor-identity", load("partner-auditor-identity"))]
named = ("bucket-policy-reports", load("bucket-policy-reports"))
whole = ("bucket-policy-account", {"Version": "2012-10-17", "Statement": [{"Sid": "TrustPartnerAccount", "Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::444455556666:root"}, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::school-reports/*"}]})
intern = "arn:aws:iam::444455556666:role/partner-intern"
print("intern, bucket names auditor ", decide(intern, "s3:GetObject", R, identity=ident, resource_policy=named, resource_account=SCHOOL)[0])
print("intern, bucket trusts account", decide(intern, "s3:GetObject", R, identity=ident, resource_policy=whole, resource_account=SCHOOL)[0])
print("intern, account, no own grant", decide(intern, "s3:GetObject", R, identity=[], resource_policy=whole, resource_account=SCHOOL)[0])
EOF
рдЦрд▒реНрдпрд╛ account рд╡рд░ (AWS CLI рдЖрдгрд┐ credentials рд▓рд╛рдЧрддрд╛рдд; S3 policy рд╕реНрд╡реАрдХрд╛рд░рдгреНрдпрд╛рдЖрдзреА role
arn:aws:iam::444455556666:role/partner-auditor рдЕрд╕реНрддрд┐рддреНрд╡рд╛рдд рдЕрд╕рд╛рдпрд▓рд╛ рд╣рд╡рд╛):
aws s3api put-bucket-policy --bucket school-reports --policy file://iam/policies/bucket-policy-reports.json
aws s3api get-bucket-policy --bucket school-reports --query Policy --output text
aws s3 cp s3://school-reports/term1.pdf . --profile partner-auditor # run as the partner's role
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
crossaccount рдЫрд╛рдкрддреЗ тЬЕ ALLOW тАФ cross-account: identity policy partner-auditor-identity#ReadSchoolReports AND resource policy bucket-policy-reports#PartnerAuditorReads both allow,
рдордЧ рддреАрди ЁЯЪл IMPLICIT DENY рдУрд│реА: рдлрдХреНрдд bucket (the caller's identity policy does not),
рдлрдХреНрдд identity (the resource policy in the other account does not), рдЖрдгрд┐ DeleteObject.
рддреБрдордЪрд╛ snippet рдЫрд╛рдкрддреЛ IMPLICIT DENY (bucket auditor рдЪреЗ рдирд╛рд╡ рдШреЗрддреЗ, intern рдЪреЗ рдирд╛рд╣реА),
ALLOW (bucket рд╕рдВрдкреВрд░реНрдг partner account рд╡рд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рддреЗ, рдЖрдгрд┐ partner рдЪреА рд╕реНрд╡рддрдГрдЪреА policy
intern рд▓рд╛ рдкрд░рд╡рд╛рдирдЧреА рджреЗрддреЗ) рдЖрдгрд┐ IMPLICIT DENY (account рд╡рд░ рд╡рд┐рд╢реНрд╡рд╛рд╕ рдареЗрд╡рдгреЗ рдкреБрд░реЗрд╕реЗ рдирд╛рд╣реА тАФ partner рдиреЗрд╣реА
рддреА рдкрд░рд╡рд╛рдирдЧреА рджреНрдпрд╛рдпрд▓рд╛ рд╣рд╡реА).
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
Accounts рдУрд▓рд╛рдВрдбрддрд╛рдирд╛ рджреЛрдиреНрд╣реА рдмрд╛рдЬреВрдВрдиреА рд╣реЛ рдореНрд╣рдгрд╛рдпрд▓рд╛ рд╣рд╡реЗ; тАж:root рдЪреЗ рдирд╛рд╡ рдШреЗрддрд▓реНрдпрд╛рдиреЗ рдХреЛрдг рд╣реЗ
рдирд┐рд╡рдбрдгреНрдпрд╛рдЪреЗ рдХрд╛рдо рджреБрд╕рд▒реНрдпрд╛ account рдЪреНрдпрд╛ рд╕реНрд╡рддрдГрдЪреНрдпрд╛ policies рдХрдбреЗ рд╕реЛрдкрд╡рд▓реЗ рдЬрд╛рддреЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- рдордЬрдмреВрдд condition рд╢рд┐рд╡рд╛рдп (рдЬрд╕реЗ
aws:PrincipalOrgID)"Principal": "*"тАФ рддреЗ public рдЖрд╣реЗ arn:aws:iam::ACCOUNT:rootрдЪрд╛ рдЕрд░реНрде "рдлрдХреНрдд рддреНрдпрд╛рдВрдЪрд╛ root user" рдЕрд╕рд╛ рдШреЗрдгреЗ тАФ рддреЗ рд╕рдВрдкреВрд░реНрдг account рдЖрд╣реЗ- bucket policy рдордзреНрдпреЗ рдкрд░рд╡рд╛рдирдЧреА рджреЗрдгреЗ рдЖрдгрд┐ caller рдЪреА рдмрд╛рдЬреВ (рдХрд┐рдВрд╡рд╛ KMS key policy) рд╡рд┐рд╕рд░рдгреЗ
ExternalIdрд╢рд┐рд╡рд╛рдп third-party roles
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: IAM Access Analyzer рдЪреЗ external access findings рддреБрдордЪреНрдпрд╛ account рдХрд┐рдВрд╡рд╛ organization рдмрд╛рд╣реЗрд░ share рдХреЗрд▓реЗрд▓рд╛ рдкреНрд░рддреНрдпреЗрдХ resource рджрд╛рдЦрд╡рддрд╛рдд тАФ рддреЗ рддрдкрд╛рд╕рдгреЗ рд╣реЗ рдХрд╛рдпрдордЪреЗ рдХрд╛рдо рдЖрд╣реЗ, рдЖрдгрд┐ bucket public рдЕрд╕рд╛рдпрд▓рд╛рдЪ рд╣рд╡реЗ рдЕрд╕реЗ рдирд╕реЗрд▓ рддрд░ S3 Block Public Access рдЪрд╛рд▓реВрдЪ рд░рд╛рд╣рддреЗ.
тПня╕П рдкреБрдвреЗ
рдбрдЭрдирднрд░ accounts рдордзреАрд▓ рд╢реЗрдХрдбреЛ рдХрд░реНрдордЪрд╛рд▒реНрдпрд╛рдВрд╕рд╛рдареА IAM users рд╡рд╛рдврддреНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рдд рдЪрд╛рд▓рдд рдирд╛рд╣реАрдд. рд▓реЛрдХ рдореЛрдареНрдпрд╛ рдкреНрд░рдорд╛рдгрд╛рд╡рд░ тАФ IAM Identity Center.
git checkout lesson-10-people-at-scale