[AWS] 팀원에게 IAM 권한을 안전하게 위임하기[AWS] 팀원에게 IAM 권한을 안전하게 위임하기

[AWS] 팀원에게 IAM 권한을 안전하게 위임하기

생성 일시
Aug 15, 2026 04:06 PM
최종 편집 일시
Last updated August 15, 2026
태그
AWS
IAM
terraform
작성자
@조준환
Date

서론

SecOps 프로젝트를 하나 맡게 되었다. 팀 근두운의 인프라를 세우는 일이었고, 자연스럽게 팀원들에게 AWS 권한을 나눠 줘야 했다. 그런데 여기서 묘한 딜레마에 부딪혔다. 인프라를 뿌리려면 팀원들이 직접 리소스를 만들 수 있어야 하는데, 하필 우리가 하는 일이 SecOps다. CloudTrail을 켜 두고 계정 전체의 API 호출을 기록하는 마당에, 그 로그에서 팀원의 일탈을 발견하고 싶지는 않았다. 팀원을 믿지 않아서가 아니라, 애초에 실수하거나 오해받을 여지 자체를 줄여 두고 싶었다.
가장 간단한 답은 각자에게 필요한 권한만 정밀하게 재단해 주는 것이다. 그러나 초기 단계의 프로젝트에서 누가 무엇을 필요로 할지 미리 다 알 수는 없다. 권한을 좁게 주면 매번 "이것도 막혔어요"라는 문의가 쏟아지고, 넓게 주면 SecOps의 명분이 무색해진다. 그래서 반대로 접근했다. 하나하나 허용하는 대신, 거의 다 허용하되 넘지 말아야 할 선만 상한으로 정해 두는 방식이다. AWS에서 이 상한 역할을 하는 것이 Permissions Boundary다. 그 경계를 설계하고 운영하며 겪은 일을 계기로, IAM 권한 위임 방법론을 조사해봤다.

IAM 권한 위임과 권한 상승 위험

리소스 권한과 IAM 권한은 위험의 결이 다르다. 팀원에게 s3:*ec2:*를 열어 주는 것은 최악의 경우 그 서비스 범위 안에서의 사고로 끝난다. 그러나 IAM 권한, 특히 iam:CreateRole, iam:PutRolePolicy, iam:AttachRolePolicy, iam:PassRole를 무심코 열어 주면 이야기가 달라진다. 이 조합은 권한의 상한 자체를 스스로 끌어올릴 수 있게 하기 때문이다. 이것을 권한 상승(privilege escalation)이라 부른다.
가장 전형적인 순서는 이렇다.
  1. iam:CreateRole로 새 역할을 하나 만든다.
  1. iam:AttachRolePolicy로 그 역할에 AdministratorAccess를 붙인다.
  1. iam:PassRole로 그 역할을 내가 통제할 수 있는 자원(예: Lambda, EC2 인스턴스 프로파일)에 넘긴다.
  1. 그 자원이 관리자 역할로 동작하기 시작한다. 이제 나는 사실상 계정 전체의 관리자다.
또는 더 짧게, 내가 이미 맡을(assume) 수 있는 역할에 iam:PutRolePolicy로 인라인 관리자 정책을 꽂아 넣는 방법도 있다. iam:PassRole은 가장 대표적인 권한 상승 경로 중 하나이며, IAM 위임 시 반드시 통제해야 한다 아무리 강력한 역할을 만들어도, 그 역할을 어떤 실행 주체에게 건네주는 행위가 막혀 있으면 그림의 떡이다.
그래서 IAM 권한 위임에서 실제로 통제해야 하는 것은 역할 생성 가능 여부가 아니라, 만들 수 있는 역할의 최대 권한 상한이다. Permissions Boundary가 이 지점을 담당한다.

Permissions Boundary 기반 경계 설계

Permissions Boundary는 IAM 사용자나 역할에 붙이는 두 번째 정책이다. 권한을 부여하는 정책이 아니라 그 주체가 가질 수 있는 권한의 상한을 정의하는 정책으로, 유효 권한은 아이덴티티 정책과 경계가 모두 허용한 것의 교집합이다. 아이덴티티 정책에서 AdministratorAccess를 줬더라도 경계가 허용하지 않는 행위는 불가능하다.
내가 근두운 계정에 적용한 경계 정책의 뼈대는 다음과 같다.
{ "Sid": "AllowEverythingByDefault", "Effect": "Allow", "Action": "*", "Resource": "*" }
시작은 전부 허용이다. 화이트리스트가 아니라 블랙리스트 방식을 택했다. 초기 프로젝트에서 팀원의 자율성을 최대한 살리되, 넘지 말아야 할 선만 명시적으로 Deny하는 전략이다. IAM에서 명시적 Deny는 어떤 Allow보다도 우선하므로, 이 아래에 쌓는 Deny들이 그대로 권한의 상한이 된다.
notion imagenotion image
그 위에 성격이 다른 Deny를 네 갈래로 얹었다.
먼저, 계정의 소유권과 지갑을 잠갔다.
{ "Sid": "DenyOwnerIdentityAndContacts", "Effect": "Deny", "Action": ["account:*ContactInformation", "account:*AlternateContact", "account:*PrimaryEmail*", "account:CloseAccount", "iam:*AccountEmailAddress"], "Resource": "*" }, { "Sid": "DenyBillingAndPaymentDetails", "Effect": "Deny", "Action": ["payments:*","invoicing:*","tax:*","billing:*","aws-portal:*"], "Resource": "*" }, { "Sid": "DenyPurchaseCommitments", "Effect": "Deny", "Action": ["ec2:Purchase*","savingsplans:*","route53domains:RegisterDomain", "aws-marketplace:Subscribe", "shield:CreateSubscription", ...], "Resource": "*" }
예약 인스턴스나 Savings Plan을 잘못 질러 놓으면 되돌릴 수 없는 약정이 되고, 도메인 등록·갱신, 마켓플레이스 구독도 마찬가지다. 계정 대표 이메일 변경이나 계정 폐쇄는 아예 프로젝트의 존립을 흔든다. 이 영역은 팀원이 선의로 접근하더라도 사고의 크기가 비대칭적으로 커서, 통째로 막았다.
다음으로, 경계가 스스로를 무력화하지 못하도록 봉인했다. 이 부분이 Permissions Boundary 설계의 핵심이자, 처음 접하면 놓치기 쉬운 지점이다.
{ "Sid": "DenyCreatePrincipalWithoutThisBoundary", "Effect": "Deny", "Action": ["iam:CreateUser","iam:CreateRole"], "Resource": "*", "Condition": { "ArnNotEquals": { "iam:PermissionsBoundary": "arn:aws:iam::<ACCOUNT_ID>:policy/KintounGuardrailBoundary" } } }
이 문장이 없으면 경계는 사실상 무력화된다. 팀원이 경계에 묶여 있어도, 경계 없는 새 역할을 만들어 거기에 관리자 권한을 붙이면 그 역할은 천장이 없다. 그래서 "새 주체를 만들 때는 반드시 이 경계를 물려주어라"를 강제한다. 경계가 자식에게 상속되도록 만드는 조건이다. 여기에 더해,
  • DenyReplacingBoundaryWithAnotherBoundary: 경계를 아예 다른 경계로 갈아치우는 것을 막고,
  • DenyBoundaryRemoval: 경계를 아예 떼어 내는 것(Delete*PermissionsBoundary)을 막고,
  • DenyBoundaryPolicyModification: 경계 정책 자체를 수정하는 것(CreatePolicyVersion, SetDefaultPolicyVersion, DeletePolicy)을 막는다.
이 세 개가 함께 있어야 경계를 우회·제거·수정하는 경로가 모두 닫힌다.
이어서, 측면 이동(lateral movement)의 사슬을 끊었다.
{ "Sid": "DenyPassRoleOutsideProjectRoles", "Effect": "Deny", "Action": "iam:PassRole", "NotResource": "arn:aws:iam::<ACCOUNT_ID>:role/project/*" }, { "Sid": "DenyAssumeRoleOutsideProjectRoles", "Effect": "Deny", "Action": "sts:AssumeRole", "NotResource": "arn:aws:iam::<ACCOUNT_ID>:role/project/*" }
앞서 말한 대로 iam:PassRole은 권한 상승의 급소다. 그래서 PassRole과 AssumeRole을 role/project/* 경로 아래의 역할로만 한정했다. 관리 역할이나 부트스트랩 역할처럼 프로젝트 네임스페이스 바깥에 있는 강력한 역할을, 팀원이 자기 컴퓨트에 넘기거나 스스로 맡는 경로를 원천 차단하는 것이다. 경로를 신뢰 경계로 쓰는 셈이다.
마지막으로, 상위 통제 평면으로의 탈출을 막았다.
{ "Sid": "DenyIdentityCenterEscape", "Effect": "Deny", "Action": ["sso:*","sso-directory:*","identitystore:*"], "Resource": "*" }, { "Sid": "DenyOrganizationsEscape", "Effect": "Deny", "Action": ["organizations:*","iam:*OrganizationsRoot*"], "Resource": "*" }
IAM 아래에서 아무리 촘촘히 막아도, 그 위에 있는 통제 평면(Organizations, IAM Identity Center)을 만질 수 있으면 전부 무의미하다. 계정 자체를 조직에서 떼어 내거나, Identity Center에서 새 권한 집합을 발급하면 경계를 통째로 우회할 수 있기 때문이다. 지금 근두운은 이 평면들을 쓰지 않지만, 나중에 도입하더라도 그건 관리자의 결정이어야 하므로 팀원 경계에서는 미리 닫아 두었다.
정리하면, 기본은 전부 허용하되 지갑·소유권·경계 자체·상위 통제 평면만 명시적으로 막는 구조다.

경계 정책의 서비스 역할 차단 사례

CloudTrail을 CloudWatch Logs에 연동하려고 하는데, iam:CreateRole이 KintounGuardrailBoundary에서 explicit deny로 막혀 있어서 관리자 계정으로도 IAM 역할 생성이 안 돼요. CloudTrail이 CloudWatch Logs에 로그 보낼 때 쓸 서비스 역할 하나만 만들어주시거나 경계 정책에서 CloudTrail 서비스 역할 생성은 예외로 허용해주실 수 있나요?
며칠 뒤, 한 팀원에게서 문의가 왔다. CloudTrail 로그를 CloudWatch Logs로 흘려보내려는데 안 된다는 것이었다. GuardDuty는 사용자가 CloudTrail trail을 별도로 구성하지 않아도 CloudTrail 이벤트의 독립 stream을 분석하지만, SIEM으로 로그를 직접 전달하려면 별도의 CloudTrail/CloudWatch Logs 구성이 필요했다.
증상은 이랬다. CloudTrail을 CloudWatch Logs에 연결하려 하면, 그 과정에서 로그를 흘려보낼 서비스 역할(신뢰 주체 cloudtrail.amazonaws.com)이 필요하다. 콘솔은 이 역할을 자동으로 만들어 주려 하는데, 바로 그 iam:CreateRole이 경계의 DenyCreatePrincipalWithoutThisBoundary에 걸렸다. 콘솔이 자동 생성하는 역할에는 당연히 우리 경계가 붙어 있지 않으니, "경계 없는 주체 생성"으로 간주되어 거부된 것이다. 이어서 그 역할을 CloudTrail에 넘기는 iam:PassRole 역시 role/project/* 바깥이라 막혔다. 심지어 관리자 계정으로도 막혔다.
경계는 요청의 의도를 구분하지 않는다. 악의적인 권한 상승이든, AWS가 정당한 통합을 위해 자동으로 만드는 서비스 역할이든, 경계 입장에서는 똑같이 "경계 없는 역할 생성"일 뿐이다. 우회할 수 없다는 장점과 정직한 자동화까지 막는 마찰이 같은 성질에서 나오는 셈이다.
결국 이 건은 관리자인 내가 직접 개입해서 해결했다. 콘솔이 자동으로 만들려던 역할을 포기하고, 서비스 역할을 경계까지 붙여 role/project/* 경로 아래에 손수 만든 다음 CloudTrail에 물려 주자 로그가 흐르기 시작했다. 애초에 막힌 것도 이 경로 때문이었다. PassRole은 role/project/* 안의 역할만 허용하는데, 콘솔이 자동 생성하던 역할은 경계도, 경로도 내 규칙과 어긋나 있었다.
notion imagenotion image
이 해결에는 걸리는 구석이 하나 있었다. 역할의 경로(path)는 IAM 콘솔에서 아예 지정할 수 없다. CLI나 API, IaC로만 넣을 수 있는 값이다. 경로를 신뢰 경계로 삼은 순간, 콘솔의 원클릭 CloudTrail → CloudWatch Logs 연동은 근본적으로 쓸 수 없게 된 셈이다. 경계에 걸리는 역할은 하나같이 콘솔 바깥에서 태어나야 했고, CLI를 두드려 역할을 파면서 나는 이 반복이 결국 코드로 정리될 일임을 체감했다.
결정적으로 이게 일회성 사건이 아니였다. 경계가 강할수록, "정당하지만 경계에 걸리는" 요청은 계속 발생할 수밖에 없다. 그때마다 팀원은 나에게 문의하고, 나는 손으로 역할을 파 준다. 경계가 훌륭한 안전망인 것은 맞지만, 그 대가로 나 자신이 병목이 되어 버렸다. 중앙 IAM 관리의 고전적인 병목이, 규모를 축소한 채로 우리 팀에서 재현된 것이다.
그래서 나는 임시방편으로 IAM 요청 창구(GitHub 이슈)를 하나 열어 두면서, 동시에 이런 생각을 했다. 차라리 팀 Terraform 레포를 만들고, IAM 역할 생성을 PR로 올리게 해서, 리뷰를 거친 뒤 apply되게 하면 되지 않을까? 손으로 파 주는 대신 코드로 리뷰하는 것이다. 그럴듯했지만, 이런 발상은 대개 나보다 먼저 누군가가 정석을 정리해 두었기 마련이라, 무작정 구현하기 전에 조사부터 하기로 했다.

IAM 권한 위임 방법론

멘토님께 여쭤보니, 기업마다 세부는 다르되 큰 그림은 대체로 다음과 같다고 했다. 요지를 옮기면 이렇다.
  • 여러 AWS 계정을 Organizations로 중앙 관리하고, 부서·서비스 단위로 계정을 분리하며, 빌링은 통합한다.
  • 임직원 접근은 계정마다 IAM 유저를 파지 않고 IAM Identity Center를 쓴다. 사내 IdP(Okta, Entra 등)를 SAML로 연동해 기존 사내 계정으로 로그인하게 하고, Identity Center에서 조직·부서별로 계정과 Permission Set을 할당한다. 실제 계정에는 그에 대응하는 IAM Role이 생기고, 사용자는 그 역할을 통해 접근한다.
  • Control Tower를 함께 쓰면 위 구성을 랜딩 존으로 표준화하고, 신규 계정 발급과 조직 전체 보안 정책을 규격화할 수 있다.
이걸 개인 프로젝트 규모의 눈높이로 다시 배열하고, 각 방식이 실제로 어떻게 굴러가는지 자료를 좀 더 찾아보았다. 이름표는 많았다. Delegated IAM administration, Permissions Boundary, 중앙 IaC/GitOps, 역할 카탈로그, Identity Center Permission Set, 멀티 계정과 SCP, ABAC, Role Vending Machine. 다만 하나씩 뜯어 보니, 통제 지점을 기준으로 권한의 상한, 변경 절차, 통제 평면의 세 갈래로 정리할 수 있었다.

권한 상한 통제(Permissions Boundary, ABAC)

지금 내가 한 방식이 여기 속한다. IAM 관리 권한 자체를 제한된 범위로 나눠 주는 것을 delegated IAM administration이라 부르는데, AWS가 2018년부터 공식 문서화해 둔 패턴이었고, AWS Security Blog의 Delegate permission management to developers by using IAM permissions boundaries 가 표준 구성을 보여 준다. 뼈대는 세 가지다. 상한을 정의하는 경계 정책, iam:PermissionsBoundary 조건 키로 "이 경계를 붙일 때만 역할 생성을 허용"하는 개발자 정책, 그리고 생성한 역할만 서비스에 넘길 수 있게 하는 PassRole 정책. 여기에 역할 이름 접두사(예시에서는 MyTestApp*)나 경로로 네임스페이스를 강제하는 것까지 포함된다.
내 경계 정책이 이 구성과 같은 뼈대임을 확인한 셈인데, 방향이 하나 다르다. AWS 예시는 개발자의 Allow 정책 쪽에 조건을 걸어 "경계 없이는 만들 수 없게" 하는 반면, 나는 경계의 Deny 쪽에 조건을 걸었다. 결과는 같지만, Deny 방식은 아이덴티티 정책을 어떻게 고쳐 주더라도 유지되므로 조금 더 보수적이다.
같은 접근의 변형으로 ABAC(태그 기반 위임)가 있다. 네임스페이스를 경로 대신 태그로 긋는 방식이다. 주체와 리소스에 팀·프로젝트 태그를 붙여 두고, aws:PrincipalTagiam:ResourceTag가 일치할 때만 역할 수정·전달을 허용하며, 새 역할을 만들 때는 aws:RequestTag 조건으로 자기 팀 태그를 붙이도록 강제한다. 내가 role/project/* 경로로 했던 구분의 일반화인 셈인데, 태그는 경로와 달리 생성 후에도 바꿀 수 있으므로 iam:TagRole, iam:UntagRole까지 함께 잠가야 한다. 팀과 프로젝트가 늘어도 정책 수가 늘지 않는 것이 장점이고, 태그 체계가 흐트러지면 권한 체계도 같이 흐트러진다는 것이 약점이다.
이 방식들은 자율성이 가장 높고 추가 인프라가 필요 없다. 대신 위에서 겪었듯 정당한 요청까지 막는 마찰이 있고, 무엇이 만들어졌는지는 사후에 CloudTrail로 확인하는 수밖에 없다.

변경 절차 통제(중앙 IaC/GitOps, 역할 카탈로그, Role Vending Machine)

모든 IAM 변경을 Terraform/CloudFormation 코드로만 표현하고, PR 리뷰를 거쳐 CI가 apply한다. 사람은 콘솔에서 IAM을 직접 만지지 않는다. 내가 떠올렸던 바로 그 방법인데, 역시 도구까지 이미 정리되어 있었다. Atlantis 같은 PR 자동화 도구가 대표적으로, PR이 열리면 웹훅으로 terraform plan을 실행해 결과를 PR 코멘트로 달아 주고, 리뷰어가 승인하면 코멘트로 apply를 트리거한다. plan과 apply 동안 state를 잠가 동시 실행 충돌도 막는다. Terraform Cloud나 GitHub Actions + OIDC로 같은 흐름을 짜는 변형도 흔하다.
통제와 감사 가능성은 가장 확실하다. 모든 변경이 diff와 리뷰 기록으로 남고, plan 출력 덕에 이 PR이 실제로 무엇을 바꾸는지를 머지 전에 눈으로 확인할 수 있다. 대신 셀프서비스 즉시성이 떨어지고, 잊지 말아야 할 점이 하나 있다. apply를 수행하는 CI의 역할이 결국 계정에서 가장 강한 권한이 되므로, 공격면이 사람에서 파이프라인으로 옮겨 갈 뿐 사라지지는 않는다. CI 역할에도 같은 경계를 물려 두는 것이 일관적이다.
여기서 요청의 자유도를 한 단계 더 좁힌 것이 사전 정의 역할 카탈로그다. "람다 실행 역할", "ECS 태스크 역할"처럼 자주 쓰는 역할을 Terraform 모듈이나 AWS Service Catalog 제품으로 미리 만들어 두고, 팀원은 "무엇이든 만들어 달라" 대신 목록에서 고른다. 리뷰 부담이 줄고 역할 품질이 균일해지지만, 카탈로그에 없는 새 요구는 결국 관리자를 거쳐야 한다.
notion imagenotion image
그리고 카탈로그를 자동화 파이프라인으로 감싼 종착점이 Role Vending Machine이다. 이름이 농담 같지만 AWS Prescriptive Guidance에 정식 패턴으로 등재되어 있다. 문서의 구현은 CI/CD 파이프라인용 역할 발급에 초점을 맞춘다. 개발자가 계정 ID, 저장소 이름, 필요한 권한 정책을 입력으로 제출하면, 벤딩 머신이 신뢰 정책과 권한 정책을 생성해 해당 저장소의 파이프라인만 그 역할을 assume할 수 있게 만들어 준다. 중앙 저장소이므로 보안팀을 필수 리뷰어로 걸어 과권한 요청을 머지 전에 반려할 수 있고, 발급 과정 자체가 규칙을 강제하므로 규칙을 벗어난 역할은 아예 만들어지지 않는다. 반복 역할이 많은 조직에서 유효하고, 구축 비용이 가장 크다.

중앙 통제 (멀티 계정, SCP, IAM Identity Center)

notion imagenotion image
마지막은 멘토님 답변의 중심이었던, 통제를 계정 안이 아니라 계정 위에서 하는 방식이다. 계정 자체를 부서·서비스 단위로 분리해 위협 반경을 나누고, Organizations의 SCP(Service Control Policy)로 조직 차원의 상한을 씌운다. SCP는 Permissions Boundary와 비슷해 보이지만 적용 범위가 다르다. 경계는 주체 하나하나에 붙여야 하고 관리자가 자기 자신에게는 안 붙일 수 있지만, SCP는 멤버 계정의 루트와 관리자를 포함한 모든 주체에게 강제된다. 즉 관리자조차 못 넘는 상한은 SCP에서만 나온다.
사람 쪽 접근은 IAM Identity Center가 맡는다. 계정마다 IAM 유저를 만드는 대신 사내 IdP(Okta, Entra 등)를 SAML로 연동하고, 이 사람이 이 계정에서 갖는 권한 묶음을 Permission Set으로 중앙에서 정의해 계정에 할당한다. 할당하면 대상 계정에 대응하는 역할이 자동 배포되고, 사용자는 SSO의 임시 자격 증명으로 그 역할을 맡아 들어가므로 장기 액세스 키가 줄어드는 부수 효과도 있다. Permission Set에도 Permissions Boundary를 지정할 수 있어서, 이 방식은 경계를 대체한다기보다 그 위에 얹힌다. 컨트롤 타워는 전체를 랜딩 존으로 묶어 신규 계정 발급과 조직 전체 보안 정책을 표준화한다. 대규모 멀티 계정의 정석이지만, 소규모 단일 계정에는 명백한 과잉이다.
이상을 몇 가지 축으로 비교하면 다음과 같다.
방식
팀원 자율성
통제 수준
운영 복잡도
감사 가능성
적합 규모
Permissions Boundary / ABAC
높음
낮음
소규모 단일 계정
중앙 IaC / GitOps
높음
높음
소~중규모
역할 카탈로그
높음
높음
반복 역할 많은 조직
Role Vending Machine
높음
높음
높음
높음
파이프라인 많은 대규모
멀티 계정 + SCP + Identity Center
매우 높음
높음
매우 높음
대규모 멀티 계정

근두운 팀 적용 방안

조사 결과를 우리 규모에 맞게 정리하면 결론은 분명했다. 우리는 지금 단일 계정에 IAM 그룹으로 역할을 나눠 관리하고 있다. 이 상태에서 랜딩 존이나 외부 IdP 연동, Control Tower까지 가는 것은 명백한 과잉이다. 그렇다면 남는 선택은 권한 상한 통제와 변경 절차 통제의 조합이다.
먼저 Permissions Boundary는 그대로 유지한다. 누가 무엇을 실수하든 핵심 자산으로의 평면 탈출만은 불가능하다는 보장이 있고, GitOps를 도입하더라도 이 상한은 남겨 둘 생각이다.
그 위에 Terraform과 PR 창구를 얹는다. 손으로 파 주던 IAM 역할 생성을 코드로 옮기고, PR 리뷰를 통과한 것만 apply되게 하는 것이다. 이러면 내가 겪은 병목이 리뷰 큐로 바뀐다. 일일이 콘솔을 여는 즉흥성 대신 깃헙 앱을 손에서 바로 열어 리뷰의 재현성과 감사 로그를 얻는 셈이다. CloudTrail 서비스 역할처럼 정당하지만 경계에 걸리는 요청도, 경계에 예외를 뚫는 대신 Terraform 모듈로 표준화해 두면 다음부터는 리뷰만으로 재사용된다. 게다가 역할의 경로처럼 콘솔로는 넣지 못하던 값도 코드에서는 한 줄이니, 앞서 손으로 겪은 불편이 그대로 사라진다.
부수적이지만 빠뜨리면 안 되는 위생 수칙도 멘토님이 강조했다. 모든 IAM 계정에 MFA는 필수이고, 액세스 키를 써야 한다면 외부 노출되지 않도록 관리해야 한다. 경계는 권한의 상한을 정할 뿐 자격 증명 자체를 지켜 주지는 않으므로, 자격 증명이 새면 그 상한 안의 권한이 통째로 유출된다.

결론

처음에는 "누가 역할을 만들 수 있는가"를 고민했지만, 겪고 보니 질문이 둘로 나뉘어 있었다. 누가 어떤 최대 권한의 역할까지 만들 수 있는가는 Permissions Boundary가 답하고, 그 상한 아래에서 실제로 무엇을 만들 것인가는 PR 리뷰가 답한다. 경계만으로는 만들어지는 역할의 내용을 사람이 보지 못하고, 리뷰만으로는 리뷰를 거치지 않은 콘솔 작업의 상한을 보장하지 못하므로, 어느 한쪽만으로는 부족했다.
경계를 세우자마자 정직한 CloudTrail 역할이 막힌 것은 성가신 사고였지만, 그 마찰이 없었다면 나는 경계만 세워 두고 스스로 병목이 된 줄도 모른 채 지나갔을 것이다. 본 포스팅은 소규모 단일 계정이라는 전제 위의 기록일 뿐이며, 규모가 달라지면 결론도 달라질 것이다. 다만 다음에 또 팀 계정을 세팅할 일이 생긴다면, 경계와 리뷰 창구를 처음부터 같이 두고 시작할 것 같다.

참고문헌