학습 목표

IAM의 구성요소 — 자격 증명과 정책

IAM은 두 종류의 대상을 다룹니다. 요청을 보내는 주체인 자격 증명(identity)과, 그 주체가 무엇을 할 수 있는지 적어 둔 정책(policy)입니다. 자격 증명에는 사용자 · 그룹 · 역할이 있고, 정책은 네 자리에 붙을 수 있습니다 — 자격 증명에, 리소스에, 권한 경계로, 그리고 세션에. 시험 문항이 어려워지는 지점은 언제나 이 네 자리에 붙은 정책이 하나의 결정으로 합쳐지는 규칙입니다.

IAM 구성요소 관계도 — 정책이 붙는 네 자리와 역할의 두 축 위쪽 절반은 하나의 요청이 평가될 때 모이는 정책 네 종류를 보여 줍니다. 자격 증명 기반 정책은 사용자·그룹·역할에 붙고, 리소스 기반 정책은 리소스 자체에 붙으며 Principal 요소를 반드시 가집니다. 권한 경계는 사용자와 역할의 상한을, 세션 정책은 AssumeRole 호출 시 전달되어 그 세션만의 상한을 정합니다. 아래쪽 절반은 IAM 역할이 두 개의 정책으로 이루어진다는 사실을 보여 줍니다. 신뢰 정책은 누가 이 역할을 맡을 수 있는가를, 권한 정책은 이 역할이 무엇을 할 수 있는가를 정합니다. 사용자와 그룹만 그린 관계도로는 이 네 자리와 두 축을 설명할 수 없습니다. 평가 시 모이는 정책 네 자리 주체와 자격 증명 IAM 사용자 장기 자격 증명 IAM 그룹 정책 그릇 · 주체 아님 IAM 역할 임시 자격 증명 요청 하나에 함께 평가됩니다 1. 자격 증명 기반 정책 사용자 · 그룹 · 역할에 부착 2. 리소스 기반 정책 리소스에 부착 · Principal 필수 3. 권한 경계 사용자 · 역할의 상한 (교집합) 4. 세션 정책 AssumeRole 시 전달 · 그 세션만 리소스 Amazon S3 버킷 버킷 정책 AWS KMS 키 키 정책 Amazon SQS 큐 큐 정책 요청 접근 IAM 역할은 정책 두 개로 이루어집니다 신뢰 정책 누가 이 역할을 맡을 수 있는가 Principal 을 적는 유일한 자리 IAM 역할 권한 정책 이 역할이 무엇을 할 수 있는가 Action 과 Resource 를 적음
IAM 구성요소의 관계 — 사용자와 그룹과 역할이 자격 증명이고, 정책은 자격 증명 · 리소스 · 권한 경계 · 세션 네 자리에 붙습니다. 역할은 신뢰 정책(누가 맡을 수 있는가)과 권한 정책(무엇을 할 수 있는가) 두 축으로 이루어집니다

사용자와 그룹 — 장기 자격 증명이 있는 쪽

IAM 사용자는 사람이나 애플리케이션에 대응하는 자격 증명이며, 콘솔 비밀번호와 액세스 키 같은 장기 자격 증명을 가질 수 있습니다. 장기라는 말은 만료되지 않는다는 뜻이고, 만료되지 않는 자격 증명은 유출되었을 때 우리가 직접 회수하기 전까지 계속 유효합니다. 이 한 문장이 이 장 전체의 방향을 결정합니다.

사용자 그룹은 권한을 묶어 관리하기 위한 장치입니다. 그룹에 자격 증명 기반 정책을 붙이면 그 그룹의 모든 사용자가 권한을 받습니다. 다만 그룹에는 시험이 노리는 제약이 세 개 있습니다.

역할 — 장기 자격 증명이 없는 쪽

IAM 역할도 권한 정책을 가진 자격 증명이지만, 사용자와 결정적으로 다른 점이 있습니다. IAM 사용 설명서는 역할에 대해 "한 사람에게 고유하게 묶이는 대신 필요한 누구든 맡을 수 있도록 만들어졌고, 비밀번호나 액세스 키 같은 표준 장기 자격 증명이 없다"고 정의합니다. 역할을 맡으면 그 자리에서 만료 시각이 있는 임시 자격 증명이 발급됩니다.

역할은 두 개의 정책으로 이루어집니다. 이 이원 구조가 역할 문항의 핵심입니다.

역할을 구성하는 두 정책
정책 무엇을 정하는가 성격
신뢰 정책(trust policy) 누가 이 역할을 맡을 수 있는가. Principal에 계정 · 사용자 · 역할 · AWS 서비스를 적는다 역할에 붙는 필수 리소스 기반 정책. 신뢰 정책에는 Principal에 와일드카드(*)를 쓸 수 없다
권한 정책(permissions policy) 이 역할이 무엇을 할 수 있는가. Action과 Resource를 적는다 자격 증명 기반 정책. 관리형 또는 인라인

"역할을 만들었는데 접근이 안 된다"는 상황은 대부분 둘 중 하나만 고친 경우입니다. 권한 정책만 넓히면 맡을 수 없고, 신뢰 정책만 넓히면 맡은 뒤에 아무것도 못 합니다.

EC2에서 API를 호출한다 — 액세스 키인가 역할인가 SAA 빈출

이 절은 이 장에서 가장 자주 출제되는 판단 하나만 다룹니다. EC2 인스턴스 위의 애플리케이션이 Amazon S3나 Amazon DynamoDB를 호출해야 할 때 무엇을 쓰는가. 정답은 거의 언제나 IAM 역할이고, 액세스 키를 인스턴스에 심는 선택지는 오답 유도로 가장 많이 쓰이는 패턴입니다.

역할 수임과 STS 임시 자격 증명 위쪽은 안티패턴입니다. EC2 인스턴스 안에 장기 액세스 키를 심어 두면 만료가 없기 때문에 유출되었을 때 사람이 직접 키를 찾아 회수하고 교체해야 합니다. 아래쪽은 권장 구성입니다. EC2 인스턴스 프로파일, 다른 계정의 주체, SAML 2.0 이나 OIDC 로 연결된 페더레이션 ID — 세 경로가 모두 AWS STS 의 AssumeRole 계열 호출로 수렴하고, 그 결과로 AccessKeyId, SecretAccessKey, SessionToken, 만료 시각을 가진 임시 자격 증명을 받습니다. 역할의 신뢰 정책이 이 주체들을 허용해야 수임이 성공하며, 임시 자격 증명은 만료되면 자동으로 무효가 되므로 회수 절차 자체가 필요 없다는 점이 두 구성을 가르는 핵심입니다. 안티패턴 — 장기 액세스 키를 심는다 EC2 인스턴스 액세스 키 파일로 저장 AWS 서비스 만료가 없습니다 유출되면 사람이 직접 회수·교체 권장 — 세 경로가 모두 AssumeRole 로 수렴한다 EC2 인스턴스 프로파일 인스턴스 메타데이터로 수령 교차 계정 주체 다른 계정의 사용자·역할 페더레이션 ID SAML 2.0 · OIDC AWS STS AssumeRole 임시 자격 증명 AccessKeyId SecretAccessKey SessionToken Expiration (만료 시각) 역할의 신뢰 정책이 위 세 주체를 허용해야 AssumeRole 이 성공합니다 임시 자격 증명은 만료되면 자동으로 무효 — 회수 절차 자체가 필요 없습니다
역할 수임과 임시 자격 증명 — EC2 인스턴스 프로파일 · 교차 계정 · 페더레이션 세 경로가 모두 AssumeRole 계열 호출을 거쳐 만료 시각이 있는 임시 자격 증명으로 수렴합니다. 왼쪽의 액세스 키를 인스턴스에 심는 방식만 유출 시 회수 작업이 필요합니다

액세스 키가 오답인 이유

이유를 "보안상 좋지 않아서"로 외우면 응용이 안 됩니다. IAM 사용 설명서가 임시 자격 증명의 장점으로 드는 항목이 그대로 근거입니다.

인스턴스에 심은 액세스 키와 IAM 역할의 임시 자격 증명 비교
항목 액세스 키를 인스턴스에 심는다 인스턴스 프로파일로 IAM 역할을 연결한다
배포물에 들어가는 것 장기 자격 증명이 AMI · 사용자 데이터 · 환경 변수 · 소스 저장소에 남는다 아무 자격 증명도 배포물에 넣지 않는다
만료 없음 — 지울 때까지 유효 있음 — 만료되면 재사용 불가
교체(rotation) 사람이 주기적으로 수행해야 한다 AWS가 자동으로 갱신한다
유출 시 대응 전 인스턴스에서 키를 찾아 회수·재배포 역할 정책만 고치면 되고, 이미 나간 자격 증명도 곧 만료된다
감사 여러 인스턴스가 같은 키를 쓰면 CloudTrail에서 구분되지 않는다 역할 세션 단위로 기록된다
권한 변경 키를 다시 발급하거나 사용자 정책을 고쳐야 한다 역할 정책을 고치면 재배포 없이 즉시 반영된다

IAM 사용자를 만들어 액세스 키를 발급하고, 그 값을 인스턴스의 환경 변수나 자격 증명 파일에 써 둡니다. 이 키는 만료되지 않으므로, 인스턴스 이미지나 로그에 한 번이라도 새어 나가면 우리가 회수할 때까지 계속 쓸 수 있습니다.

안티패턴 — 인스턴스에 장기 자격 증명을 심는다
aws configure set aws_access_key_id "$APP_KEY_ID"
aws configure set aws_secret_access_key "$APP_SECRET"
aws s3 cp ./report.csv s3://example-app-reports/

역할을 만들어 인스턴스 프로파일로 연결하면 자격 증명을 코드에 넣지 않습니다. SDK와 CLI가 기본 자격 증명 체인으로 임시 자격 증명을 알아서 찾아 씁니다.

권장 — 인스턴스 프로파일로 역할을 연결한다 (리소스 ID는 예시입니다)
aws ec2 associate-iam-instance-profile \
  --instance-id i-0123456789abcdef0 \
  --iam-instance-profile Name=AppServerProfile

# 애플리케이션 쪽에는 아무 설정도 하지 않습니다.
aws s3 cp ./report.csv s3://example-app-reports/

인스턴스 프로파일 — 역할을 인스턴스에 붙이는 그릇

EC2 인스턴스에는 역할을 직접 붙이지 않고 인스턴스 프로파일(instance profile)이라는 그릇을 통해 붙입니다. 인스턴스 프로파일 하나에는 역할 하나가 들어갑니다. 콘솔에서 역할을 만들면 같은 이름의 인스턴스 프로파일이 함께 만들어져서 이 계층이 잘 보이지 않지만, CLI나 CloudFormation으로 만들 때는 직접 만들어야 합니다.

app-server-role.json — EC2 서비스가 맡을 수 있게 하는 신뢰 정책
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowEc2ToAssumeThisRole",
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

Principal이 사람이나 계정이 아니라 서비스라는 점을 눈여겨봅니다. "이 역할은 EC2 서비스가 맡을 수 있다"는 선언이며, 이 문장이 없으면 인스턴스 프로파일에 넣어도 자격 증명이 나오지 않습니다.

애플리케이션은 어떻게 자격 증명을 찾는가

SDK와 AWS CLI는 정해진 순서로 자격 증명을 탐색합니다. 환경 변수와 자격 증명 파일이 앞쪽에 있고, 인스턴스 메타데이터가 뒤쪽에 있습니다. 그래서 액세스 키를 환경 변수에 남겨 두면 역할을 붙여도 그 키가 먼저 쓰입니다. 역할로 전환할 때는 옛 키를 지우는 것까지가 한 작업입니다.

verify-identity.sh — 지금 어떤 자격 증명으로 호출되고 있는지 확인
# 역할이 제대로 붙었다면 Arn 이 assumed-role/... 형태로 나옵니다.
aws sts get-caller-identity \
  --query '[Account,Arn]' \
  --output text

정책 문서의 구조

IAM 정책은 JSON 문서입니다. 요소의 순서는 의미가 없지만 어떤 요소가 있고 없느냐가 정책의 종류를 결정합니다. 특히 Principal의 유무가 자격 증명 기반 정책과 리소스 기반 정책을 가릅니다.

IAM 정책 문서 구조 해부 실제 JSON 정책 문서를 왼쪽에 놓고 오른쪽에 각 요소의 역할을 붙인 해부도입니다. Version 은 정책 언어 버전이고, Statement 는 명령문 배열이며, 그 안에서 Effect 가 Allow 또는 Deny 를, Action 이 어떤 API 작업을, Resource 가 어떤 리소스 ARN 을, Condition 이 언제 적용되는지를 정합니다. 강조된 Principal 행이 이 그림의 결론입니다. Principal 은 누구에게 허용하는가를 적는 요소이며 리소스 기반 정책에만 존재합니다. 자격 증명 기반 정책은 이미 붙어 있는 사용자·그룹·역할이 곧 주체이므로 Principal 을 적지 않습니다. 아래 두 카드가 이 비대칭을 나란히 대비시킵니다. 정책 문서 (JSON) 각 요소가 답하는 질문 {   "Version": "2012-10-17",   "Statement": [{     "Sid": "AllowRead",     "Effect": "Allow",     "Principal": {"AWS": "arn:aws:iam::111122223333:root"},     "Action": ["s3:GetObject"],     "Resource": "arn:aws:s3:::my-bucket/*",     "Condition": {       "StringEquals": {"aws:PrincipalOrgID": "o-ab12cd34"}     }   }] } 정책 언어 버전 (고정값) 명령문 배열 · 여러 개 가능 선택 · 사람이 읽는 식별자 Allow 인가 Deny 인가 누구에게 — 여기가 핵심 어떤 API 작업을 어떤 리소스 ARN 에 언제 — 조건 키 자격 증명 기반 정책 Principal 없음 주체는 정책이 붙은 대상 자신 리소스 기반 정책 Principal 필수 누구에게 허용할지 적어야 함 이 비대칭이 두 정책 유형을 구분하는 가장 빠른 표식입니다
정책 문서의 요소 해부 — Version과 Statement 아래에 Sid, Effect, Action, Resource, Condition이 놓이고, Principal은 리소스 기반 정책에만 나타납니다. Action과 NotAction, Resource와 NotResource, Principal과 NotPrincipal은 각각 함께 쓸 수 없습니다

요소별 역할

IAM JSON 정책의 주요 요소
요소 역할 주의
Version 정책 언어 버전. 현행 값은 2012-10-17 날짜처럼 보이지만 버전 식별자다. 정책을 만든 날짜가 아니다
Statement 실제 규칙을 담는 블록. 배열로 여러 개를 넣는다 문장 하나하나가 독립적으로 평가된다
Sid 문장 식별자. 사람이 읽기 위한 이름표 선택 사항이지만 붙여 두면 감사와 디버깅이 쉬워진다
Effect Allow 또는 Deny Deny는 다른 모든 Allow를 이긴다
Principal 누구에게 적용되는가. 계정 · 사용자 · 역할 · AWS 서비스를 지정한다 리소스 기반 정책(역할 신뢰 정책 포함)에만 있다. 자격 증명 기반 정책에는 쓰지 않는다
Action 대상 API 작업. s3:GetObject처럼 서비스:작업 형식 NotAction과 같은 문장에 함께 쓸 수 없다
Resource 대상 리소스의 ARN NotResource와 함께 쓸 수 없다. 버킷과 객체는 서로 다른 ARN이다
Condition 추가 조건. 조건 키와 연산자로 적용 범위를 좁힌다 없으면 항상 적용된다. 조건이 거짓이면 그 문장은 적용되지 않는다
read-reports-bucket.json — 자격 증명 기반 정책. Principal이 없다
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListTheBucket",
      "Effect": "Allow",
      "Action": "s3:ListBucket",
      "Resource": "arn:aws:s3:::example-app-reports"
    },
    {
      "Sid": "ReadObjectsUnderPrefix",
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::example-app-reports/daily/*"
    }
  ]
}

두 문장이 나뉜 이유가 곧 시험 포인트입니다. s3:ListBucket은 버킷에 대한 작업이라 대상이 arn:aws:s3:::버킷이름이고, s3:GetObject는 객체에 대한 작업이라 대상이 arn:aws:s3:::버킷이름/키입니다. 하나의 ARN으로 둘 다 처리하려다 "목록은 되는데 읽기가 안 된다"가 나옵니다.

Condition — 최소 권한을 만드는 도구

조건은 "누가 무엇을"에 "어떤 상황에서"를 더합니다. 전역 조건 키는 어느 서비스에서나 쓸 수 있고, 서비스별 조건 키도 있습니다.

require-mfa-and-tls.json — MFA와 전송 중 암호화를 요구하는 조건
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyWhenNotUsingTls",
      "Effect": "Deny",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::example-app-reports",
        "arn:aws:s3:::example-app-reports/*"
      ],
      "Condition": {
        "Bool": { "aws:SecureTransport": "false" }
      }
    },
    {
      "Sid": "RequireMfaForDeletes",
      "Effect": "Deny",
      "Action": "s3:DeleteObject",
      "Resource": "arn:aws:s3:::example-app-reports/*",
      "Condition": {
        "BoolIfExists": { "aws:MultiFactorAuthPresent": "false" }
      }
    }
  ]
}

두 문장 모두 Effect가 Deny라는 점이 중요합니다. "TLS를 쓸 때만 허용"을 Allow + 조건으로 쓰면 다른 정책의 Allow를 막지 못합니다. 강제하고 싶은 규칙은 조건부 Deny로 씁니다.

관리형 정책과 인라인 정책

관리형 정책과 인라인 정책의 차이
구분 성격 언제 쓰는가
AWS 관리형 정책 AWS가 만들고 유지한다. 여러 계정에서 같은 이름으로 쓸 수 있다 표준적인 역할을 빠르게 세울 때. 다만 대체로 필요보다 넓다
고객 관리형 정책 우리가 만들고 버전을 관리한다. 여러 자격 증명에 재사용된다 기본 선택. 최소 권한을 직접 설계할 때
인라인 정책 자격 증명 하나에 파묻힌다. 그 자격 증명이 지워지면 함께 사라진다 정책과 자격 증명의 일대일 관계를 강제하고 싶을 때

리소스 기반 정책은 관리형이 될 수 없고 항상 인라인입니다. S3 버킷 정책이나 KMS 키 정책을 "관리형 정책으로 만들어 여러 버킷에 붙인다"는 서술은 성립하지 않습니다.

정책 평가 로직 — 최종 결정이 나오는 순서 SAA 빈출

여러 정책이 동시에 적용될 때 AWS가 결정을 내리는 절차는 정해져 있습니다. IAM 사용 설명서의 서술을 그대로 옮기면 기본은 암묵적 거부이고, 어떤 정책에서든 명시적 거부가 하나라도 있으면 즉시 거부이며, 명시적 허용만이 기본 거부를 뒤집습니다.

IAM 정책 평가 순서 흐름도 하나의 API 요청이 최종 결정에 이르기까지 거치는 관문을 위에서 아래로 그린 흐름도입니다. 모든 요청은 기본적으로 암묵적으로 거부된 상태에서 출발합니다. 첫 관문에서 정책 유형을 통틀어 명시적 Deny 를 찾고, 하나라도 있으면 나머지를 보지 않고 즉시 거부합니다. 이어서 Organizations SCP 의 상한, 리소스 기반 정책, 권한 경계, 세션 정책, 자격 증명 기반 정책을 차례로 평가하며, 어느 한 관문이라도 허용하지 않으면 오른쪽 거부 레일을 따라 최종 거부로 빠집니다. 리소스 기반 정책이 명시적으로 허용하면 동일 계정 주체는 왼쪽 지름길을 따라 곧바로 최종 허용에 도달합니다. 결론은 명시적 거부가 명시적 허용을 이기고, 명시적 허용이 기본값인 암묵적 거부를 이긴다는 우선순위입니다. 기본값은 암묵적 거부입니다 — 명시적 Allow 가 있어야만 통과합니다 API 요청 도착 Principal · Action · Resource · Condition 1. 명시적 Deny 가 있는가 모든 정책 유형을 통틀어 먼저 검사 2. SCP 가 허용하는가 상한만 정함 · 루트 사용자에도 적용 3. 리소스 기반 정책이 Allow 인가 동일 계정이면 여기서 허용될 수 있음 4. 권한 경계가 허용하는가 자격 증명 기반 정책과 교집합 5. 세션 정책이 허용하는가 AssumeRole 호출 시 전달한 정책 6. 자격 증명 기반 정책이 Allow 인가 사용자 · 그룹 · 역할에 붙은 정책 아니오 예 Allow 없음 예 예 예 예 · 즉시 거부 아니오 · 상한 밖 아니오 · 경계 밖 아니오 · 세션 밖 아니오 · 암묵 거부 예 · 지름길 최종 결정: 허용 명시적 Allow 가 있고 어떤 Deny 에도 걸리지 않음 최종 결정: 거부 명시적 Deny 또는 Allow 없음
IAM 정책 평가 흐름 — 요청이 들어오면 먼저 모든 정책에서 명시적 거부를 찾고, 하나라도 있으면 그 자리에서 거부로 확정됩니다. 거부가 없으면 SCP · 권한 경계 · 세션 정책이 만드는 상한을 통과해야 하고, 마지막으로 자격 증명 기반 또는 리소스 기반 정책의 명시적 허용이 있어야 요청이 통과합니다

세 단계로 요약한 우선순위

  1. 암묵적 거부(implicit deny) — 아무 정책도 언급하지 않은 작업은 거부됩니다. 이것이 기본값이며, 계정 루트 사용자만 예외입니다.
  2. 명시적 허용(explicit allow) — 자격 증명 기반 정책이나 리소스 기반 정책에 Allow가 있으면 기본 거부를 덮습니다.
  3. 명시적 거부(explicit deny) — 어느 정책에 있든 Deny가 하나라도 있으면 앞의 모든 허용을 이깁니다. 거부는 되돌릴 수 없습니다.

따라서 우선순위는 명시적 거부 > 명시적 허용 > 암묵적 거부입니다. 실무에서 이 성질이 유용한 이유는, "무슨 일이 있어도 막아야 하는 것"을 딱 한 군데에 Deny로 적으면 아래쪽에서 실수로 허용해도 뚫리지 않기 때문입니다.

합집합인가 교집합인가

평가 순서보다 자주 틀리는 것이 결합 규칙입니다. 조합에 따라 "둘 중 하나만 허용해도 통과"와 "둘 다 허용해야 통과"가 갈립니다.

정책 유형별 결합 규칙
조합 결합 의미
자격 증명 기반 + 리소스 기반 (같은 계정) 합집합 둘 중 하나만 허용해도 통과한다
자격 증명 기반 + 리소스 기반 (교차 계정) 양쪽 모두 필요 호출자 계정과 리소스 계정이 둘 다 허용해야 한다
자격 증명 기반 + 권한 경계 교집합 경계가 허용하지 않는 작업은 정책이 허용해도 못 한다
자격 증명 기반 + SCP 교집합 SCP가 상한이며 SCP만으로는 권한이 생기지 않는다
자격 증명 기반 + 세션 정책 교집합 세션 정책은 역할의 권한을 줄이기만 한다
SCP + 권한 경계 + 자격 증명 기반 셋 다 허용해야 함 하나라도 빠지면 거부된다

규칙을 하나로 압축하면 이렇습니다. 권한을 주는 정책끼리는 합쳐지고, 상한을 정하는 정책은 곱해집니다. 여기에 "명시적 거부는 어느 정책에 있든 전부를 이긴다"를 얹으면 평가 로직이 끝납니다.

자격 증명 기반 정책과 리소스 기반 정책

같은 접근을 허용하는 방법이 두 가지 있습니다. 주체 쪽에 "너는 저기에 갈 수 있다"고 적거나, 리소스 쪽에 "저 사람은 들어와도 된다"고 적는 것입니다. 어느 쪽에 적느냐가 관리 방식과 교차 계정 동작을 바꿉니다.

자격 증명 기반 정책과 리소스 기반 정책의 결합 규칙 같은 두 정책이 동일 계정과 교차 계정에서 서로 다르게 결합한다는 것을 진리표로 증명합니다. 왼쪽 동일 계정에서는 자격 증명 기반 정책과 리소스 기반 정책이 합집합으로 작동하므로 둘 중 하나만 허용해도 요청이 통과합니다. 오른쪽 교차 계정에서는 호출자 계정의 자격 증명 기반 정책과 리소스 소유 계정의 리소스 기반 정책이 양쪽 모두 허용해야만 통과하고, 한쪽만 허용하면 거부됩니다. 단 어느 쪽 구성이든 어느 정책에든 명시적 거부가 하나라도 있으면 그것이 모든 허용을 이깁니다. 동일 계정 교차 계정 계정 A IAM 사용자 S3 버킷 자격 증명 기반 정책 버킷 정책 계정 A IAM 사용자 자격 증명 기반 정책 계정 B S3 버킷 버킷 정책 자격 증명 기반 리소스 기반 결과 Allow 없음 허용 없음 Allow 허용 Deny Allow 거부 계정 A 자격 증명 계정 B 버킷 정책 결과 Allow 없음 거부 없음 Allow 거부 Allow Allow 허용 합집합 (union) 둘 중 하나만 Allow 여도 통과 양쪽 모두 필요 두 정책이 모두 Allow 여야 통과 어느 구성이든 어느 정책에든 명시적 Deny 가 하나 있으면 그것이 이깁니다
두 정책 유형의 결합 — 같은 계정 안에서는 자격 증명 기반과 리소스 기반 중 하나만 허용해도 통과하지만, 계정 경계를 넘으면 호출자 계정의 자격 증명 기반 정책과 리소스 계정의 리소스 기반 정책이 모두 허용해야 통과합니다

리소스 기반 정책을 지원하는 대표 리소스

모든 서비스가 리소스 기반 정책을 지원하지는 않습니다. IAM 사용 설명서는 예로 Amazon S3 버킷, Amazon SQS 큐, VPC 엔드포인트, AWS KMS 키를 듭니다. 여기에 IAM 역할의 신뢰 정책도 리소스 기반 정책이라는 사실을 더하면 시험 범위가 거의 덮입니다.

자격 증명 기반 정책과 리소스 기반 정책 비교
항목 자격 증명 기반 정책 리소스 기반 정책
붙는 곳 IAM 사용자 · 그룹 · 역할 리소스 자체 (버킷 · 큐 · 키 · 역할)
Principal 요소 없다 — 붙은 대상이 곧 주체 있다 — 누구인지 명시해야 한다
관리형 여부 관리형 또는 인라인 인라인만
교차 계정 단독으로는 불가 다른 계정의 주체를 직접 지정할 수 있다
관리 관점 "이 사람이 어디에 갈 수 있나"를 한곳에서 본다 "이 리소스에 누가 올 수 있나"를 한곳에서 본다

교차 계정 접근 — 양쪽이 모두 허용해야 한다

계정 경계를 넘는 순간 규칙이 바뀝니다. IAM 사용 설명서는 이 점을 명시적으로 강조합니다 — 계정 A의 호출자는 계정 B의 리소스를 부를 수 있는 자격 증명 기반 정책을 가져야 하고, 동시에 계정 B의 리소스 기반 정책이 계정 A의 호출자를 허용해야 합니다. 양쪽에 정책이 없으면 요청은 실패합니다.

구현 방법은 두 갈래이고, 무엇을 공유하느냐로 갈립니다.

교차 계정 접근의 두 가지 구현
방식 동작 고르는 기준
역할 수임(AssumeRole) 리소스 계정에 역할을 만들고 신뢰 정책에 상대 계정을 적는다. 호출자는 역할을 맡아 리소스 계정의 주체가 되어 행동한다 기본 선택. 여러 서비스에 접근해야 하거나, 리소스 기반 정책을 지원하지 않는 서비스가 섞여 있을 때
리소스 기반 정책 직접 허용 버킷 정책이나 큐 정책의 Principal에 상대 계정 주체를 적는다. 호출자는 자기 계정의 주체인 채로 접근한다 대상이 리소스 한 종류일 때. 역할 전환 없이 자기 자격 증명으로 접근시키고 싶을 때
reports-bucket-policy.json — 다른 계정의 역할에 읽기를 허용하는 버킷 정책 (계정 ID는 예시입니다)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPartnerAccountRoleToRead",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/AnalyticsReader"
      },
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::example-app-reports",
        "arn:aws:s3:::example-app-reports/*"
      ]
    }
  ]
}

이 정책만으로는 부족합니다. 계정 123456789012 쪽에서도 AnalyticsReader 역할에 s3:GetObject를 허용하는 자격 증명 기반 정책이 붙어 있어야 합니다. S3 접근 제어의 나머지 절반(퍼블릭 액세스 차단, 객체 소유권)은 8장 S3와 오브젝트 스토리지에서 다룹니다.

AWS STS와 역할 수임

AWS Security Token Service(STS)는 임시 보안 자격 증명을 발급하는 서비스입니다. 발급된 자격 증명은 액세스 키 ID · 비밀 액세스 키 · 세션 토큰 세 값으로 이루어지고, 만료 시각이 있습니다. IAM 사용 설명서는 임시 자격 증명의 장점으로 "장기 자격 증명을 애플리케이션에 배포하거나 심을 필요가 없다"와 "수명이 제한되어 있으므로 교체하거나 명시적으로 폐기할 필요가 없다"를 듭니다.

상황에 따라 다른 API

임시 자격 증명을 발급하는 STS 작업
작업 언제 쓰는가 특징
AssumeRole 같은 계정 안의 권한 전환, 교차 계정 접근 호출자가 이미 AWS 자격 증명을 가지고 있어야 한다
AssumeRoleWithSAML 기업 디렉터리 페더레이션 (SAML 2.0 기반) 기업 ID 저장소를 AWS 역할에 연결한다. 사용자별 AWS 자격 증명이 필요 없다
AssumeRoleWithWebIdentity 웹 · 모바일 앱의 외부 IdP 로그인 (OIDC 호환) 호출에 AWS 자격 증명이 필요 없다. 모바일 앱에는 Amazon Cognito가 권장된다
GetSessionToken IAM 사용자가 MFA로 보호된 API 호출을 해야 할 때 IAM 사용자의 장기 자격 증명으로 호출한다. 역할 전환이 아니다
assume-cross-account-role.sh — 교차 계정 역할 수임 (계정 ID는 예시입니다)
aws sts assume-role \
  --role-arn arn:aws:iam::123456789012:role/AnalyticsReader \
  --role-session-name analytics-batch \
  --external-id example-external-id \
  --duration-seconds 3600 \
  --query 'Credentials.Expiration'

신뢰 정책과 외부 ID

역할을 만드는 쪽(신뢰하는 계정, 리소스 소유자)이 신뢰 정책에 상대 계정(신뢰받는 계정)을 적습니다. 문제는 상대 계정이 우리와 같은 조직이 아닐 때입니다. 상대 계정 전체를 신뢰하면 그 계정의 모든 주체가 역할을 맡을 수 있게 됩니다.

외부 ID(external ID)는 이때 쓰는 장치입니다. STS API 문서는 "교차 계정 역할은 보통 한 계정 전체를 신뢰하도록 설정되므로, 신뢰하는 계정의 관리자가 외부 ID를 발급해 그 ID를 아는 사람만 역할을 맡게 한다"고 설명합니다. 서드파티 서비스에 우리 계정 접근을 위임할 때의 표준 구성입니다.

third-party-trust-policy.json — 외부 ID와 MFA를 요구하는 신뢰 정책
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPartnerWithExternalId",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "example-external-id"
        },
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

세션 길이와 역할 연쇄

세션 길이는 무한정 늘릴 수 없습니다. STS API 문서에서 확인되는 값은 다음과 같습니다.

STS 세션 길이 관련 확인된 값
항목 값 근거
AssumeRole의 DurationSeconds 최소 900초(15분)부터 역할에 설정된 최대 세션 길이까지 역할의 최대 세션 길이는 1시간에서 12시간 사이로 설정할 수 있다
역할 연쇄(role chaining) 세션이 최대 1시간으로 제한된다 1시간을 넘는 DurationSeconds를 주면 작업이 실패한다
GetSessionToken IAM 사용자 기준 900초(15분)–129,600초(36시간), 기본 43,200초(12시간) STS API 문서 본문에 명시
세션 정책 길이 인라인과 관리형 정책 ARN을 합쳐 평문 2,048자까지, 관리형 정책 ARN은 최대 10개 STS API 문서 본문에 명시

역할 연쇄란 역할로 받은 임시 자격 증명으로 또 다른 역할을 맡는 것입니다. 여기서 자주 나오는 함정이 하나 있습니다 — EC2 인스턴스가 인스턴스 프로파일의 역할로 API를 호출하는 것은 역할 연쇄가 아닙니다. 따라서 1시간 제한도 적용되지 않습니다.

상한을 정하는 정책 — SCP와 권한 경계

지금까지의 정책은 권한을 주는 쪽이었습니다. 여기서 다루는 두 가지는 권한을 주지 않고 상한만 정합니다. 둘을 구분하는 것이 도메인 1에서 반복적으로 요구됩니다.

SCP · 권한 경계 · 세션 정책의 상한 관계 세 겹 벤 다이어그램으로 실효 권한이 세 상한의 교집합이라는 것을 보입니다. 왼쪽 위 원은 Organizations SCP, 오른쪽 위 원은 권한 경계, 아래 원은 세션 정책이며 세 원이 모두 겹치는 가운데 영역만이 실제로 사용할 수 있는 권한입니다. 세 정책 모두 권한을 부여하지 않고 상한만 정하므로, 이 교집합 안이라도 자격 증명 기반 정책이나 리소스 기반 정책이 명시적으로 허용해야 요청이 통과합니다. SCP 는 멤버 계정의 루트 사용자에게도 적용되고, 권한 경계는 자격 증명 기반 정책과 교집합으로 작동하며, 세션 정책은 AssumeRole 호출 시 전달되어 그 세션에만 적용됩니다. 또한 어느 정책에든 명시적 거부가 하나라도 있으면 교집합과 무관하게 즉시 거부됩니다. SCP 조직 상한 권한 경계 주체 상한 세션 정책 세션 상한 실효 권한 가운데 교집합 안에서만 권한이 생깁니다 여기에 명시적 Allow 까지 있어야 통과합니다 SCP — 조직 차원의 상한 권한을 부여하지 않습니다 멤버 계정 루트 사용자에도 적용 권한 경계 — 주체의 상한 자격 증명 기반 정책과 교집합 경계만으로는 권한이 생기지 않음 세션 정책 — 세션의 상한 AssumeRole 호출 시 전달 역할의 권한을 더 좁힙니다 명시적 Deny 는 교집합을 무시 어느 정책에든 Deny 가 하나라도 있으면 그 즉시 거부됩니다
실효 권한은 교집합입니다 — SCP가 정한 계정 상한, 권한 경계가 정한 엔터티 상한, 세션 정책이 정한 세션 상한, 그리고 자격 증명 기반 정책의 허용이 모두 겹치는 영역만 실제로 수행됩니다

서비스 제어 정책(SCP) — 계정 전체의 상한

SCP는 AWS Organizations의 정책이며, 조직 루트 · OU · 개별 계정 중 어디에나 붙습니다. 성질은 두 문장으로 요약됩니다.

조직을 전체 기능으로 만들어야 SCP를 쓸 수 있습니다. 통합 결제 전용으로 만든 조직에서는 어떤 정책 유형도 활성화되지 않습니다 (1장 AWS Organizations).

deny-leaving-organization.json — 멤버 계정이 조직을 이탈하지 못하게 막는 SCP
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyLeaveOrganization",
      "Effect": "Deny",
      "Action": [
        "organizations:LeaveOrganization",
        "account:CloseAccount"
      ],
      "Resource": "*"
    }
  ]
}

권한 경계 — 엔터티 하나의 상한

권한 경계는 관리형 정책을 IAM 사용자나 역할 하나에 상한으로 붙이는 기능입니다. IAM 사용 설명서의 표현으로는 "자격 증명 기반 정책이 그 엔터티에 부여할 수 있는 최대 권한을 설정"하며, "권한을 제한할 뿐 그 자체로는 권한을 주지 않습니다." 실효 권한은 자격 증명 기반 정책과 권한 경계의 교집합입니다.

가장 중요한 용도는 권한 관리 업무의 위임입니다. 개발팀장에게 "사용자와 역할을 만들 수 있는 권한"을 주고 싶은데 그대로 주면 관리자 권한을 가진 사용자를 만들어 버릴 수 있습니다. 새로 만드는 엔터티에 특정 권한 경계를 반드시 붙이도록 조건을 걸면 위임하면서도 상한을 유지할 수 있습니다.

delegated-user-creation.json — 지정한 권한 경계를 붙일 때만 사용자 생성을 허용
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CreateUsersOnlyWithBoundary",
      "Effect": "Allow",
      "Action": [
        "iam:CreateUser",
        "iam:AttachUserPolicy"
      ],
      "Resource": "*",
      "Condition": {
        "StringEquals": {
          "iam:PermissionsBoundary": "arn:aws:iam::123456789012:policy/TeamBoundary"
        }
      }
    }
  ]
}

SCP와 권한 경계는 무엇이 다른가

SCP와 권한 경계 비교
항목 서비스 제어 정책(SCP) 권한 경계
적용 범위 계정 전체 (조직 루트 · OU · 계정에 부착) IAM 사용자 또는 역할 하나
소속 서비스 AWS Organizations IAM
루트 사용자에 적용 적용된다 적용되지 않는다 — 루트는 IAM 엔터티가 아니다
그룹에 붙일 수 있나 해당 없음 불가 — 사용자와 역할에만 붙는다
권한 부여 하지 않는다 하지 않는다
대표 용도 조직 차원 가드레일 — 리전 제한, 특정 서비스 차단, 조직 이탈 방지 권한 관리 위임 — 개발자가 만드는 역할의 최대치를 고정

AWS IAM Identity Center와 페더레이션 선택

계정이 늘어나면 계정마다 IAM 사용자를 만드는 방식이 무너집니다. 입사자가 오면 계정 수만큼 사용자를 만들어야 하고, 퇴사자가 나가면 계정 수만큼 지워야 하며, 하나라도 빠뜨리면 접근이 남습니다. 이 문제를 푸는 것이 페더레이션이고, AWS의 표준 답이 AWS IAM Identity Center입니다.

AWS IAM Identity Center 로그인 흐름과 구식 구성 비교 위쪽은 권장 구성입니다. Active Directory 나 외부 IdP 같은 외부 ID 소스가 AWS IAM Identity Center 한 곳에 연결되고, 권한 집합이 정책 묶음을 정의하며, Identity Center 가 계정마다 그 권한 집합에 대응하는 역할을 만들어 두고 사용자는 로그인 후 그 역할을 수임합니다. 자격 증명은 외부 ID 소스 한 곳에만 존재하고 각 계정에는 임시 자격 증명만 흘러갑니다. 아래쪽은 구식 구성입니다. 계정마다 IAM 사용자와 비밀번호, 액세스 키를 따로 만들면 사람 수와 계정 수의 곱만큼 장기 자격 증명이 늘어나고 퇴사자 회수 지점도 그만큼 늘어납니다. 권장 — 자격 증명이 한 곳에만 존재한다 외부 ID 소스 Active Directory 외부 IdP (SAML) 또는 내장 디렉터리 IAM Identity Center 단일 로그인 포털 사용자·그룹을 여기서 한 번만 관리 권한 집합 Permission Set 재사용 가능한 정책 묶음 계정 A — 역할 수임 계정 B — 역할 수임 계정 C — 역할 수임 계정에는 임시 자격 증명만 흘러갑니다 — 계정 안에 IAM 사용자를 만들지 않습니다 구식 — 계정마다 IAM 사용자를 만든다 계정 A IAM 사용자 · 비밀번호 장기 액세스 키 계정 B IAM 사용자 · 비밀번호 장기 액세스 키 계정 C IAM 사용자 · 비밀번호 장기 액세스 키 같은 사람이 계정마다 별도 자격 증명을 갖습니다 사람 수 × 계정 수만큼 자격 증명이 늘고, 퇴사 시 회수 지점도 그만큼 늘어납니다
IAM Identity Center의 로그인 경로 — 외부 ID 소스나 내장 디렉터리에서 인증한 뒤, 권한 집합이 각 계정의 역할로 변환되어 역할 수임으로 이어집니다. 자격 증명은 한 곳에만 존재하고 계정 쪽에는 IAM 사용자가 만들어지지 않습니다

권한 집합이 하는 일

IAM Identity Center는 사용자와 그룹을 한 곳에서 관리하고, 권한 집합(permission set)을 만들어 "어느 그룹이 어느 계정에서 무엇을 할 수 있는가"를 정의합니다. 권한 집합을 계정에 할당하면 그 계정 안에 대응하는 역할이 자동으로 만들어지고, 사용자는 로그인 포털에서 계정과 역할을 골라 임시 자격 증명을 받습니다.

결과적으로 얻는 것은 세 가지입니다.

무엇을 고를 것인가 — 페더레이션 판단 기준

시험은 서비스를 설명하게 하지 않고 고르게 합니다. 기준은 누구에게 접근을 주는가 하나입니다.

대상별 페더레이션 선택 기준
누구에게 무엇을 고르는가 신호가 되는 표현
사내 직원에게 여러 AWS 계정 접근을 준다 AWS IAM Identity Center "여러 계정", "중앙에서 관리", "직원이 입퇴사한다", "단일 로그인"
기존 SAML IdP를 계정 하나에 직접 연결한다 IAM의 SAML 2.0 자격 증명 공급자 + 역할 "기존 IdP를 그대로", "계정이 하나뿐"
모바일 · 웹 앱의 최종 사용자에게 준다 Amazon Cognito (자격 증명 풀) "모바일 앱 사용자 수백만", "소셜 로그인", "게스트 접근"
EC2 인스턴스에 Active Directory 도메인 참여가 필요하다 AWS Directory Service "도메인 조인", "Windows 파일 서버", "그룹 정책"
AWS 안에서 실행되는 워크로드에 준다 IAM 역할 (사람이 개입하지 않는다) "인스턴스에서", "Lambda 함수가", "태스크가"

Amazon Cognito와 AWS Directory Service의 세부 동작은 16장 보안·암호화·거버넌스에서 다룹니다. 여기서는 사람 대 직원이면 Identity Center, 사람 대 앱 사용자면 Cognito, 사람이 아니면 역할이라는 세 갈래만 확실히 해 둡니다.

흔한 오해

시험 포인트 정리

이 장의 주제는 전부 보안 아키텍처 설계(30%)에 속합니다. 아래 표의 함정 열이 실제 오답 선택지가 만들어지는 자리입니다.

확인 문제

이 장의 핵심을 확인하는 10문항입니다. 키보드만으로 완주할 수 있습니다 — 숫자키 1~5로 선택지를 고르고 Enter로 제출합니다.

학습용 유형 연결형과 순서 배열 문항이 섞여 있을 수 있습니다. 이 두 유형은 암기 확인에 효율이 좋아서 기본개념 확인 문제에만 넣었으며, 실제 SAA-C03 시험에는 출제되지 않습니다.

이어서 볼 곳

공식 문서 출처

이 장의 개념 서술과 API 동작은 모두 아래 문서에서 확인했습니다.