자주 마주치는 상황 FAQ
증상 → 원인 → 설정 순서. 관점 필터로 개발자가 부딪히는 문제와 DevOps가 설정할 일을 나눠 볼 수 있다.
찾기
디버깅
AccessDenied가 떴는데 어디서 막힌 건지 모르겠다개발자DevOps 관리자
User: arn:aws:sts::…:assumed-role/… is not authorized to perform: ec2:RunInstances …
오류 문장의 끝부분이 막은 정책 종류를 알려준다. 그 종류에 따라 고칠 사람이 달라진다.
aws sts get-caller-identity로 지금 누구인지 먼저 확인. 프로필·계정 착각이 가장 흔한 원인- "no identity-based policy allows" → ⑤ 부족 (Permission Set 수정, DevOps)
- "explicit deny in a service control policy" / "resource control policy" → 조직 정책 (DevOps)
- "permissions boundary" → Boundary 범위 밖 / "session policy" → 세션 정책
- "no resource-based policy allows" → 버킷·키·트러스트 정책 쪽
- CloudTrail 이벤트 기록에서 errorCode가 AccessDenied인 이벤트의 errorMessage · userIdentity 확인
aws sts get-caller-identity --profile dev-power
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=RunInstances \
--max-results 5 --profile dev-power
로그인 · CLI
CLI가 "SSO session … has expired"라며 멈춘다개발자DevOps 관리자
Error when retrieving token from sso: Token has expired and refresh failed
포털(SSO) 토큰 만료. Role 임시 키 만료와는 별개다.
aws sso login --sso-session me다시 실행- 포털 세션 길이는 Identity Center 설정(기본 8시간)에서, Role 세션 길이는 Permission Set 세션 시간(1~12시간)에서 조정
- 자주 끊겨 불편하면 포털 세션은 늘리고, PlatformAdmin 같은 고권한 Role 세션은 짧게 유지
계정·역할이 여러 개라 프로필 전환이 헷갈린다개발자DevOps 관리자
프로필 이름이 무엇을 하는 모자인지 드러나지 않아서.
- sso-session 하나에 프로필을 "계정-역할"로 나눈다
- 터미널마다
AWS_PROFILE을 고정하고 셸 프롬프트에 표시 - 고권한 프로필은 이름부터 위험하게 보이게 (admin-platform)
- 콘솔은 멀티 세션으로 역할별로 나눠 동시에 열기
[profile dev-ro]
sso_session = me
sso_account_id = 222222222222
sso_role_name = ReadOnly
[profile dev-power]
sso_session = me
sso_account_id = 222222222222
sso_role_name = DevPowerUser
[profile admin-platform]
sso_session = me
sso_account_id = 111111111111
sso_role_name = PlatformAdmin
로컬 서버나 Docker 컨테이너에서 AWS를 호출해야 한다개발자
.env에 액세스 키를 넣는 습관이 장기 키 유출로 이어진다.
- 호스트 실행:
AWS_PROFILE=dev-power만 지정하면 SDK가 SSO 캐시를 사용 - 컨테이너: ~/.aws를 읽기 전용 마운트하고 AWS_PROFILE 지정
- 또는 단기 키만 환경변수로 주입 (만료되면 다시 export)
docker run -v ~/.aws:/root/.aws:ro -e AWS_PROFILE=dev-power app
# 단기 키를 환경변수로
eval "$(aws configure export-credentials --profile dev-power --format env)"
콘솔에서 지금 어느 계정·역할인지 자꾸 헷갈린다개발자DevOps 관리자
Permission Set 이름이 의도를 드러내지 않거나, 여러 역할을 한 탭에서 번갈아 쓴다.
- Permission Set 이름을 의도가 보이게: ReadOnly / DevPowerUser / PlatformAdmin
- 콘솔 우측 상단의 Role 이름과 계정 ID 확인 습관
- 콘솔 멀티 세션으로 역할별 탭 분리
- PlatformAdmin 세션은 1시간으로 짧게
권한 설계
개발자에게 dev 계정 Admin을 줘도 될까?DevOps 관리자
Admin이면 IAM으로 자기 권한을 마음대로 늘릴 수 있다.
- dev: PowerUserAccess + IAM은 Boundary 조건부 허용. 앱 Role은 만들 수 있지만 권한 상승은 불가
- 운영 계정: ReadOnly 기본, 변경은 배포 파이프라인 경유
- 1인 구성: 일상은 DevPowerUser, 조직 변경 때만 PlatformAdmin
{
"Effect": "Allow",
"Action": ["iam:CreateRole", "iam:PutRolePolicy", "iam:AttachRolePolicy"],
"Resource": "arn:aws:iam::222222222222:role/app-*",
"Condition": {"StringEquals": {
"iam:PermissionsBoundary": "arn:aws:iam::222222222222:policy/AppBoundary"}}
}
같은 Permission Set인데 dev는 넓게, prod는 좁게 하고 싶다DevOps 관리자
Permission Set 내용은 할당된 모든 계정에 똑같이 찍힌다.
- 방법 A: Permission Set을 분리 (DevPowerUser / ProdOperator)
- 방법 B: Permission Set이 고객 관리형 정책을 "이름"으로 참조 → 계정마다 같은 이름, 다른 내용의 정책을 둔다
- B는 계정별 차등이 깔끔하지만 각 계정의 정책을 IaC로 관리해야 한다
aws sso-admin attach-customer-managed-policy-reference-to-permission-set \
--instance-arn arn:aws:sso:::instance/ssoins-xxxx \
--permission-set-arn arn:aws:sso:::permissionSet/ssoins-xxxx/ps-xxxx \
--customer-managed-policy-reference Name=AppDeveloper,Path=/
Permission Set을 고쳤는데 반영이 안 된다DevOps 관리자개발자
재프로비저닝을 안 했거나, 참조한 고객 관리형 정책이 대상 계정에 없어 프로비저닝이 실패했다.
- Permission Set 화면에서 계정 상태가 업데이트 필요인지 확인
provision-permission-set실행 후 상태 조회- 실패 사유가 정책 없음이면 대상 계정에 같은 이름·경로로 정책 생성
aws sso-admin describe-permission-set-provisioning-status \
--instance-arn arn:aws:sso:::instance/ssoins-xxxx \
--provision-permission-set-request-id <요청 ID>
실수로 비싼 리소스를 띄우는 걸 막고 싶다DevOps 관리자
Identity 정책만으로는 Admin급 세션의 실수를 막기 어렵다.
- SCP로 인스턴스 타입 허용 목록 + 리전 제한
- AWS Budgets 알림을 함께 설정
- SCP는 사람·CI 모두에 걸리지만 관리 계정은 예외
{
"Effect": "Deny",
"Action": "ec2:RunInstances",
"Resource": "arn:aws:ec2:*:*:instance/*",
"Condition": {"StringNotLike": {"ec2:InstanceType": ["t4g.*", "t3.*"]}}
}
사람·프로젝트가 늘면 권한을 어떻게 나누나 (ABAC)DevOps 관리자
프로젝트마다 Permission Set을 만들면 조합이 폭발한다.
- IdP 사용자 속성(team 등)을 Identity Center의 접근 제어 속성으로 넘긴다 → 세션 태그 aws:PrincipalTag/team
- 정책은 리소스 태그와 비교 → 프로젝트가 늘어도 Permission Set 하나
- 리소스 생성 시 태그 강제는 태그 정책·SCP로
{
"Effect": "Allow",
"Action": ["ec2:StartInstances", "ec2:StopInstances"],
"Resource": "*",
"Condition": {"StringEquals": {
"aws:ResourceTag/team": "${aws:PrincipalTag/team}"}}
}
CI · 워크로드
ECS · Lambda 배포 때 iam:PassRole 권한이 없다고 나온다개발자DevOps 관리자
… is not authorized to perform: iam:PassRole on resource: arn:aws:iam::…:role/app-…
서비스에 Role을 넘기는 주체(사람 또는 CI)는 그 Role에 대한 PassRole이 필요하다.
- 배포 주체 정책에 대상 Role ARN만 PassRole 허용 + PassedToService 조건
- "*"로 열면 아무 Role이나 서비스에 붙여 권한 상승이 가능해진다
{
"Effect": "Allow",
"Action": "iam:PassRole",
"Resource": "arn:aws:iam::222222222222:role/app-*",
"Condition": {"StringEquals": {"iam:PassedToService": "ecs-tasks.amazonaws.com"}}
}
GitHub Actions에서 "Not authorized to perform sts:AssumeRoleWithWebIdentity"DevOps 관리자CI 파이프라인
토큰과 Trust 조건이 안 맞는다. 원인은 대부분 아래 넷 중 하나.
- 워크플로에
permissions: id-token: write가 없음 - Trust의 sub 조건 불일치. environment를 쓰면 sub 형식이 바뀐다
- aud가 sts.amazonaws.com이 아님
- OIDC provider가 그 계정에 등록되지 않음
repo:<owner>/zandi-wiki:ref:refs/heads/main # 브랜치 push
repo:<owner>/zandi-wiki:environment:production # environment 사용 시
repo:<owner>/zandi-wiki:pull_request # PR 이벤트
다른 계정의 S3 버킷에 접근하면 403개발자CI 파이프라인
크로스 어카운트는 양쪽 허용이 모두 필요하다. 같은 계정 감각으로 한쪽만 열어서 생기는 문제.
- 호출자 Identity 정책 Allow + 버킷 정책에 호출자 Role ARN Allow
- SSE-KMS 버킷이면 키 정책도 호출자를 허용
- Object Ownership을 BucketOwnerEnforced로 두면 ACL 문제가 사라짐
S3 일반 객체는 되는데 암호화된 객체만 AccessDenied개발자
SSE-KMS 키에 대한 kms:Decrypt 권한이 없거나 키 정책이 허용하지 않는다.
- Role에 해당 키 ARN으로 kms:Decrypt 허용
- 키 정책에 계정 위임 문구 또는 Role 직접 허용이 있는지 확인
- S3를 통해서만 쓰게 하려면 kms:ViaService 조건
{
"Effect": "Allow",
"Action": "kms:Decrypt",
"Resource": "arn:aws:kms:ap-northeast-2:222222222222:key/<key-id>",
"Condition": {"StringEquals": {"kms:ViaService": "s3.ap-northeast-2.amazonaws.com"}}
}
외부 SaaS(모니터링 등)에 내 계정 접근 권한을 줘야 한다DevOps 관리자
액세스 키를 발급해 넘기면 회수·추적이 어렵다.
- SaaS 계정을 신뢰하는 Role을 만들고 sts:ExternalId 조건 추가 (혼동된 대리인 방지)
- 권한은 읽기 전용 최소로
{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<SaaS 계정 ID>:root"},
"Action": "sts:AssumeRole",
"Condition": {"StringEquals": {"sts:ExternalId": "<SaaS가 준 값>"}}
}
계정 · 조직
관리 계정(admin)에서 서비스를 돌려도 될까?DevOps 관리자
관리 계정은 SCP가 적용되지 않고, 결제·조직 권한과 같은 경계 안에 있다.
- 장기적으로 prod 멤버 계정을 따로 만들어 워크로드를 옮기고, admin은 Organizations · 결제 · Identity Center 전용
- 당장 어렵다면 admin 할당 Permission Set을 최소화하고, 관리 계정 리소스는 Role 정책으로 직접 좁힌다
- Route 53 zone은 admin에 두고 서브도메인만 위임하는 방식도 가능
Identity Center 관리를 관리 계정 밖으로 빼고 싶다DevOps 관리자
일상적인 사용자·권한 관리를 위해 관리 계정에 자주 들어가는 것 자체가 위험이다.
- 멤버 계정(예: shared)을 Identity Center 위임 관리자로 등록 → 일상 관리는 거기서
- 관리 계정 대상 할당과 관리 계정에 프로비저닝된 Permission Set은 위임 관리자가 다룰 수 없어 관리 계정에서 처리
aws organizations register-delegated-administrator \
--account-id 333333333333 \
--service-principal sso.amazonaws.com
계정마다 루트 이메일·MFA 관리가 부담된다DevOps 관리자
멤버 계정 루트가 계정 수만큼 늘어난다.
- 중앙 루트 관리 활성화 → 멤버 루트 자격증명 삭제, 새 계정은 루트 없이 생성
- 이메일은 plus addressing(me+dev@…)으로 한 메일함에 모으기
- 관리 계정 루트만 패스키·보안키 MFA, 액세스 키 없음
aws organizations enable-aws-service-access --service-principal iam.amazonaws.com
aws iam enable-organizations-root-credentials-management
aws iam enable-organizations-root-sessions
보안 · 감사
Identity Center나 IdP가 장애면 어떻게 들어가나?DevOps 관리자
모든 사람 접근이 SSO 하나에 걸려 있다.
- 비상 경로 준비: 관리 계정 루트(MFA, 오프라인 보관) 또는 MFA를 강제한 비상용 IAM 사용자 1개
- 비상 경로 사용 시 바로 알림이 오게 설정
- 리전 장애 대비는 Identity Center 멀티 리전 복제
- 분기마다 비상 경로 로그인 테스트
// EventBridge 규칙: 루트 콘솔 로그인 감지
{
"detail-type": ["AWS Console Sign In via CloudTrail"],
"detail": {"userIdentity": {"type": ["Root"]}}
}
기존 IAM User 액세스 키를 걷어내고 싶다DevOps 관리자
용도를 모른 채 지우면 무언가가 조용히 깨진다.
- 자격 증명 보고서로 키 목록과 마지막 사용일 확인
- 용도별 대체: 사람 → SSO, CI → OIDC, 서버 → Role, 외부 SaaS → ExternalId Role, 온프레미스 → IAM Roles Anywhere
- 키 비활성화 → 며칠 관찰 → 삭제
aws iam generate-credential-report
aws iam get-credential-report --query Content --output text \
| base64 -d | cut -d, -f1,9,10,11
누가 무엇을 했는지 추적하고 싶다DevOps 관리자개발자
계정·리전마다 로그를 따로 보면 놓친다.
- 조직 CloudTrail trail(모든 계정 · 리전)을 별도 버킷으로
- Identity Center 세션은 assumed-role/…/사용자이름 형태라 사람 단위 추적 가능
- IAM Access Analyzer의 미사용 접근 분석으로 안 쓰는 권한·키 정리
aws cloudtrail create-trail --name org-trail \
--s3-bucket-name org-trail-logs \
--is-organization-trail --is-multi-region-trail