목차


AWS IAM은 반드시 공부하자

모든 법률의 가장 기본이 되는 여섯 가지 법률을 일컬어 육법(六法)이라고 합니다. 육법에는 헌법, 민법, 형법, 상법, 형사소송법, 민사소송법 등이 있습니다. 이 육법은 다른 특별한 법률과 하위 법령의 기반이 되어 법체계를 떠받치고 있습니다. 이와 같이 AWS에서도 전체 서비스의 기반이 되는 중요한 서비스들이 있습니다. AWS의 기본이 되는 서비스를 말하라고 한다면, 저는 중요한 순서대로 다음 세가지를 꼽습니다.

image

AWS의 다른 서비스들은 네이밍이 괴상한 것으로 유명합니다. 그나마 위 서비스들의 이름에는 납득할만한 의미가 들어있습니다. 전에는 서비스 아이콘도 서비스 내용과는 전혀 무관한 3D 입체 도형이었는데, 요즘에는 이런 스타일로 바뀌었습니다. 아주 조금 더 알아보기 쉬운 것 같습니다.


EC2는 사실상 컴퓨터 그 자체로서, 다른 많은 서비스들이 EC2를 기반으로 연결되어 있습니다. EC2를 그냥 사용하는데는 어려움이 없지만, EC2를 사용하기 위해 네트워크를 구성하고 권한을 부여하는 일에 더 많은 신경을 써야 합니다. AWS에서는 네트워크와 보안(인증 + 접근 제어) 업무를 각각 VPC와 IAM에서 담당합니다. 그래서 VPC와 IAM을 이해하는 것이 중요한데, 그중에서 IAM은 거의 모든 AWS 서비스를 이용하는데 필수적으로 연관되므로 더더욱 중요합니다. 따라서 IAM을 제대로 알아야 앞으로 필요한 구성을 이해한 상태에서 AWS 서비스를 이용할 수 있습니다.

이번 글에서는 AWS IAM에 관해 다룹니다. 특히 IAM의 요소 중에서 Policy에 관해 알아보겠습니다. 앞으로 IAM Policy를 설정할 때, 마치 엔지니어가 도면을 보듯이 그 의미를 이해할 수 있도록 몇가지 중요한 개념을 알아보겠습니다.


주니어가 클라우드 서비스에 대해서 여쭙자, 아키텍트께서 말씀하셨다.
"온디맨드 컴퓨팅(EC2), 구성 가능한 네트워크(VPC) 그리고 보안(IAM)이다."

주니어가 말하였다.
"어쩔 수 없어서 한 가지를 버려야 한다면 세 가지 가운데 어느 것을 먼저 버려야 합니까?"
"온디맨드 컴퓨팅을 버린다."

주니어가 여쭈었다.
"어쩔 수 없어서 또 한 가지를 버려야 한다면 어느 것을 먼저 버려야 합니까?"

"구성 가능한 네트워크를 버린다. 예로부터 리소스는 어디에나 있는 것이지만, 보안이 없으면 서비스는 존립하지 못하느니라."

<운어(雲語), 암아존편>


대상 독자


기본 개념과 용어 정리

기본 개념과 용어 몇 개를 간단히 훑어보고 가겠습니다.

  • IAM Group
  • IAM User
  • IAM Role
  • IAM Policy
  • Access Control
  • RBAC (Role-Based Access Control)
  • ABAC (Attribute-Based Access Control)

image

그림에 나오는 IAM 메뉴 항목이 각각 Group, User, Role, Policy 입니다.


UBAC (User-Based Access Control)

잘 사용하지 않는 용어입니다만, 설명을 위해서 가져왔습니다.

어떤 특정한 행동을 할 수 있고(Allow), 할 수 없는(Deny) 권한을 통제하는 것을 Access Control(접근 제어)라고 합니다.

가장 단순한 방법은 그 권한을 사용자에게 직접 부여하는 것입니다.

# 권한 설정
사용자B1: b 가능
사용자A2: a 가능
사용자A1: a 가능
사용자B2: b 가능

사용자가 얼마 안 될 때는 몰라도 나중에는 점점 권한 관리가 지루하고 엉성해집니다. 좀 더 구조적으로 관리할 수단이 필요할 것 같습니다.

그런데 가만히 보니 사용자들 가운데 군집이 있는 것을 발견합니다.

# 권한 설정
사용자A1: a 가능
사용자A2: a 가능

사용자B1: b 가능
사용자B2: b 가능

이렇게 보니 사용자Ax, 사용자Bx가 각각 같은 권한이 있는 군집을 이루는 것을 알게 됩니다.

그래서 그룹의 개념을 넣으면 어떻게 될까요?


GBAC (Group-Based Access Control)

이 말도 역시 잘 쓰이지는 않는 것 같습니다.

사용자에게 직접 권한을 주는 것보다, 그룹에다 권한을 주고 사용자를 그룹에 넣으면 더 좋지 않을까요?

이제는 이렇게 바뀝니다.

# 그룹 권한 설정
그룹A: a가능
그룹B: b가능

# 사용자 그룹 설정
사용자A1: 그룹A
사용자A2: 그룹A
사용자B1: 그룹B
사용자B2: 그룹B

그런데 권한이 다양하게 존재하면 그룹도 점점 복잡하게 됩니다.

# 그룹 권한 설정
그룹A: a가능
그룹B: b가능
그룹C: [a가능, c가능]
그룹D: [a가능, c불가, d가능]

# 사용자 그룹 설정
사용자A1: 그룹A
사용자A2: [그룹A, 그룹D]
사용자B1: [그룹B, 그룹C]
사용자B2: [그룹B, 그룹D]

그리고 권한 검사를 하는데 그룹으로 조건을 거는 것이 어려울 수 있습니다.

예를 들면 권한 a가 가능한 그룹에 그룹A, 그룹C, 그룹D가 있는데 ‘어느 그룹 소속이냐’ 이런식으로 권한을 검사하기는 어렵습니다.

그래서 여기서 추가로 Role(역할)이라는 개념이 나타납니다.


RBAC (Role-Based Access Control)

이 용어는 확실히 많이 쓰입니다. RBAC하면 대개 이것을 가리킵니다.

그룹에다가 권한을 바로 주는 대신에 권한의 논리적 집합으로서 역할을 만들고 역할을 그룹이나 사용자에 연결합니다.

즉 Group은 UserGroup으로 주로 사용하고, Role은 권한의 Group으로 사용하는 것입니다. (간접 계층 추가)

권한 검사를 할 때 Group에 대해서 조건을 거는 것보다는, 좀 더 보안적인 측면에 가까운 Role에 대해서 규칙을 설정하는 것이 쉽습니다.

그래서 AWS의 많은 서비스에서 권한을 설정할 때는 IAM Group은 사용되지 않고 대신 IAM Role을 지정하는 부분이 많습니다.

저는 Group은 울타리에 비유하고, Role은 포스트잇에 비유합니다. (태그 같은 거라고 봐도 됩니다.)

Role은 User에 붙이든 Group에 붙이든 잘 붙습니다. (sticky)

참고로 Role이 있다고 해서 Group을 사용하지 말라는 것이 절대 아닙니다.

이전에 Group이라는 개념만 가지고 세분화된 접근 제어를 하기 위해서 그룹을 많이 만들어야 했었는데,

  • a를 할 수 있는 그룹
  • b를 할 수 있는 그룹
  • zz 할 수 있는 그룹

역시 UBAC 만큼이나 정신 없습니다.

그래서 대신 Role 개념을 추가해서 권한 관계를 신경쓰고, Group은 Group 답게 User와의 관계만 신경쓰도록 하게 되었습니다.

  • 그룹
    • 관리자 그룹
    • 사용자 그룹
    • 게스트 그룹
  • 역할
    • a할 수 있는 역할
    • b할 수 있는 역할

역시 울타리 보다는 포스트잇이 탈부착이 쉽지요?

관건은 울타리도 쓰고 포스트잇도 쓰되 본연의 뜻에 맞게 적절히 사용하는 것입니다.


ABAC (Attribute-Based Access Control)

이것도 많이 쓰이는 용어입니다. (PBAC - Policy-Based Access Control과 혼용되기도 합니다.)

주의: RBAC vs. ABAC가 아닙니다. (배타적인 개념이 아님)

지금까지 UBAC부터 GBAC, 그리고 RBAC까지 개념을 살펴봤는데,

뭔가 느낌을 받으신 분들도 있겠지만 일반적으로 RBAC 수준이 되어도 여전히 한계가 있습니다.

좀 더 미세하게 접근제어를 하기 위해서는 무언가 더 필요합니다. (ABAC를 위한 떡밥)

예를 들어, 아래와 같은 접근 제어 리스트가 있다고 가정합니다.

[사용자]
김진호 중사 (그룹: [7내무반])
김한국 일병 (그룹: [7내무반])

[그룹]
7내무반 (역할: [병기관리, 탄약관리(추가 예정)])

[역할]
병기관리 (권한: [소총 청소])
탄약관리 (권한: [탄약고 개방]) (추가 예정)

[권한]
Allow 소총 청소
Allow 탄약고 개방 (추가 예정)

원래 7내무반 그룹에는 병기관리 역할만 있었는데, 새로 탄약관리 역할을 추가하려고 합니다.

여기서 김진호 중사는 간부라서 탄약고 개방이 허용되고, 김한국 일병은 병사라서 탄약고 개방이 불허됩니다.

그러면 접근 제어 리스트를 어떻게 구성할 수 있을까요?

  • 기존 그룹을 건드리면 안 된다.
  • 소속을 나타내는 7내무반 외에 다른 그룹을 만들어서 할당하면 안 된다.

이 제약 조건에 따르면, 현재 가능한 유일한 방법은 그룹을 우회해서, 김진호 중사에게 직접 탄약 관리 역할을 할당하는 것입니다. (여기서 ‘아 그건 아니지!’ 하고 느끼셨다면… 100%입니다.)

하지만 사용자 수준에 직접 역할을 주면 그룹 수준의 관리가 안 되기 때문에 점점 어수선해질 가능성이 있습니다. (급하면 그렇게 할 수도 있겠지요.)

그런데 만약 탄약관리 역할은 7내무반 그룹에 부여하되, 그것이 사용자 계급이 간부인지, 병사인지에 따라서 적용이 달리 된다면 어떨까요?

여기서 계급은 사용자가 가진 속성(attribute)의 하나입니다.

그리고 역할에 붙는 권한 부여 형식이, 단지 뭐를 허용(Allow)이나 불허(Deny)한다고 하는 명제 형식이 아니라,

만약 ~하면 ~한다는 식의 조건문 형식으로 붙는다면 동적인 권한 부여가 가능합니다.

이를 유식한 말로 술어 논리(Predicate Logic)라고 합니다. Predicate가 True를 반환할 때에 한해서 적용됩니다.

그러면 이제 접근 제어 리스트를 이렇게 작성할 수 있습니다.

[사용자]
김진호 중사 (그룹: [7내무반])
김한국 일병 (그룹: [7내무반])

[그룹]
7내무반 (역할: [병기관리, 탄약관리])

[역할]
병기관리 (정책: [소총 청소])
탄약관리 (정책: [탄약고 개방])

[정책]
Allow 소총 청소 (조건 없는, 단순 권한 부여)
Allow 탄약고 개방 if 사용자.간부인가? == True (Subject 속성 사용)
Allow 탄약고 개방 if 탄약고.name == '간이 탄약고' (Object 속성 사용)
Allow 탄약고 개방 if 현재시각 BETWEEN 09:00 AND 12:00 (Global/Environment/Context 속성 사용)

눈치가 빠르신 분은 [권한][정책]으로 바뀐 것을 알아차리셨을 겁니다.

이때 정책(Policy)은 술어논리(Predicate Logic)를 사용해서 동적(dynamic)이면서, 조건적(conditional)으로 권한을 부여할 수 있게 하는 요소입니다.

속성을 참조하고 반영하기 때문에 ABAC이고, Policy를 열거하므로 PBAC라고도 하는 이유입니다.

IAM의 Policy가 바로 이런 개념입니다. (그래서 AWS IAM은 RBAC + ABAC 융합)

이것은 기존 RBAC 구조를 그대로 유지하면서, 권한을 부여하는 형식으로서 Policy라는 개념이 추가된 것입니다.

하지만 지금까지 사용한 용어들은 문서마다 조금씩 다른 개념으로 사용하니, AWS IAM에 한정해서라고 생각하시면 되겠습니다.

다음에는 IAM Policy의 JSON 문법을 살펴보고, 어떤 형식으로 어떻게 작성하는지를 보면서 이해하도록 하겠습니다.


IAM Policy의 JSON 문법

AWS로 조금이라도 밥벌이를 해보신 분이라면, IAM Policy가 JSON 형식으로 작성된다는 것 쯤은 알고 계실 겁니다.

저도 따로 설명서를 보고 공부했던 것은 아니지만, 계속 보다보니 대충 뭐가 들어가는지는 알게 되었습니다.

그런데 설명서를 보니 제가 모르는 것들이 더 많았습니다. 공부해야 할 것들이 많더라 하는 것입니다.

앞으로 IAM 설명서는 다 외울 때까지 계속 읽어보려고 합니다.

IAM JSON 정책 요소 참조

자 그럼 IAM Policy의 JSON 모양을 살펴보겠습니다.


루트 (최상위 요소)

{
  "Version": "2012-10-17",
  "Statement": [...]
}

이 모양은 항상 고정입니다. 즉 JSON 루트 바로 아래에 VersionStatement 속성은 항상 들어갑니다.

  • Version:
    • string
    • IAM Policy JSON 문서 양식 버전
    • default가 2008-10-17이긴 한데, 2012-10-17을 사용해야 하므로 항상 넣어야 합니다.
  • Statement:
    • array
    • 권한 부여 규칙(Rule 혹은 Policy)의 나열
  • Id:
    • 그냥 이런게 있었구나 하고 넘어갑니다. (…)

용어가 헷갈리네? Policy vs. Policy

제가 JSON 전체를 Policy라고 말하고, 또 Statement 배열 안에 들어가는 요소도 Policy라고 하니까 헷갈리시지요? Statement 배열 안에 들어가는 각 Statement 요소도 제가 위에서 설명한 것처럼 개념상 Policy와 연결됩니다. 대신 용어상 혼란을 방지하기 위해서 앞으로는 JSON 전체를 일컬어 Policy라고 하겠습니다. (잘 구분하세요) 그리고 Statement 요소는 그냥 Statement라고 하겠습니다. (Policy 루트의 속성 이름을 Statements라고 해야 안 헷갈리는데…)


Statement (Statement 배열 안의 각각의 요소)

예시: AWS S3의 musma 버킷에 있는 객체를 읽을 수 있게 함 (조건이 안 붙은 단순한 권한 부여)

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::musma/*"
    }
  ]
}

이런 속성들이 있습니다.

  • Effect
    • enum: Allow | Deny
    • 허용한다는 규칙인지, 불허한다는 규칙인지 구분
    • 아마 Allow만 많이 보셨을 겁니다.
  • Action
    • string | Array<string>
    • 하나 혹은 여러 개의 Action을 지정할 수 있습니다.
    • AWS 서비스에 사용되는 작업, 리소스 및 조건 키
      • 각 서비스별로 고유의 서비스 접두사(예: DynamoDB는 dynamodb)가 있습니다.
      • 위 설명서에서 각 서비스를 선택해서 들어가면 XX에서 정의한 작업이라는 단락에 작업 목록이 있습니다.
      • Action은 (서비스 접두사):(작업) 형식으로 작성합니다.
        • 예: dynamodb:DeleteItem, s3:GetObject
  • Resource
    • Statement의 주제가 되는 리소스를 한정(qualify)합니다.
    • 서비스에 따라서 이렇게 해당 서비스에 속한 하부 리소스 단위까지 한정할 수 있습니다. (DynamoDB의 테이블 수준까지 한정)
      {
        "Effect": "Allow",
        "Action": "dynamodb:*",
        "Resource": "arn:aws:dynamodb:::table/musma" // 이런 형식을 ARN이라고 합니다. (ARN 참조)
      }
      
    • 리소스를 특정할 수 없는 일부 서비스에서는, Resource를 비워두는 대신 *를 입력합니다.
  • Principal
    • object (Principal)
    • 리소스 기반 정책에서, 보안 주체를 지정합니다.
  • Sid
    • string
    • Statement ID
    • 각 요소에 Unique ID를 붙이고 싶을 때 사용

이렇게 IAM Policy의 JSON 문법을 살펴보았습니다. 각각의 속성이 무엇을 가리키는 대충 알아보았으니 아마 다시 IAM Policy를 볼 때면 이전 보다 더 뚜렷하게(?) 보이기를 기대합니다.

혹시 ARN에 대해서 궁금하시면…


IAM Policy의 종류

Policy라고 다 같은 Policy가 아닙니다.

image

정책(Policy) 앞에 달리는 수식어는 다양합니다.

  • 연결 대상이 어디인가에 따라
    • 자격 증명 주체(User, Group, Role)에
      • 자격증명-기반 정책(Id-Based Policy)
    • 리소스에
      • 리소스-기반 정책(Resource-Based Policy)
    • Role의 신뢰 관계
      • 신뢰 정책 (사실 Role을 리소스로 본다면, 특별한 의미의 리소스-기반 정책이라고 할 수 있음)
  • 누가 만들었냐에 따라
    • 내가
      • 고객 관리 정책
    • AWS가 만든 빌트인 정책
      • AWS 관리 정책
      • 직무 기반 정책
  • IAM Role에 인라인으로 선언되었으면
    • 인라인 정책

뭐가 많지만 진짜 중요한 두 가지 유형은 아래와 같습니다.

  • 자격증명-기반 정책(Id-Based Policy)
  • 리소스-기반 정책(Resource-Based Policy)

정책이라는 것은 사실 “(어떤 Condition을 만족할 때,) 어떤 Resource에 대해서 어떤 Action을 할 수 있게 허용/불허(Effect)한다.”라는 의미를 담은 것이지요.

그런데 위의 문장 성분 중에서 뭐가 빠졌습니까?

네, 주어(Subject)가 빠졌습니다. 이것을 보안 주체(Principal)라고 합니다.

완전한 정책이 되려면, “(어떤 Principal이) (어떤 Condition을 만족할 때,) 어떤 Resource에 대해서 어떤 Action을 할 수 있게 허용/불허(Effect)한다.” 이렇게 되어야 합니다.


자격증명-기반 정책(Id-Based Policy)

그런데 자격증명-기반 정책(Id-Based Policy)으로 사용할 때는, 그 정책에 연결된 보안 주체(AWS 계정, IAM 사용자, 그룹, 역할 혹은 연합 인증된 사용자, Cognito User Identity 등이 될 수 있음)가 암묵적인 Principal이 됩니다.

그래서 여러분이 자주 보던 정책의 Statement에서는 대개 Principal 속성이 없었다는 것을 깨달았을 것입니다.

IAM 메뉴의 정책 리스트에 나오는 정책들은 모두 자격증명-기반 정책(Id-Based Policy)입니다.


리소스-기반 정책(Resource-Based Policy)

자격증명 기반 정책은 ‘이 정책과 연결된 보안주체는 어떤 대상에 대해 이러이러한 권한이 부여된다’는 의미였습니다.

그런데 반대로 객체(대상)를 중심으로 생각을 해보면 어떨까요? (마치 능동태를 수동태로 바꾸듯이)

‘이 정책과 연결된 보안주체는 어떤 대상에 대해 이러이러한 권한이 부여된다’

‘이 대상에 대해 이러이러한 권한누구누구누구에게 부여된다’

리소스-기반 정책은 AWS의 서비스 중에서 일부 서비스에서 사용됩니다.

예를 들어, S3의 버킷의 권한 메뉴에 들어가면 버킷 정책을 편집할 수 있습니다.

image

리소스-기반 정책을 사용하는 서비스 중에서 대표적으로 S3가 있습니다.

아래 예시 내용 살펴보겠습니다.

Version2008-10-17인데, 옛날 문서 형식을 사용하고 있습니다. 자동으로 생성할 때는 아직 2008 형식도 사용되는 것 같습니다.

{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36E6CTWWW86E5"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mcas.musma.net/*"
        }
    ]
}

Version, Id, Sid 이런 속성들은 내용을 이해하는데 필요없으므로 제외합니다. Effect도 Allow이니 그냥 빼겠습니다.

{
    "Statement": [
        {
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36E6CTWWW86E5"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::mcas.musma.net/*"
        }
    ]
}

Statement가 하나 밖에 없으니, 하나의 Statement만 집중해서 보겠습니다.

{
    "Principal": {
        "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36E6CTWWW86E5"
    },
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::mcas.musma.net/*"
}

자 그럼 해석해볼까요?


ARN 읽는 방법

위의 정책에서 ARN이 두 개 있습니다.

원래 ARN은 arn:aws:(서비스 Prefix):(AWS 리전 이름):(AWS 계정):(리소스 한정자) 이런 순서로 적는데, 여기서 (AWS 리전 이름), (AWS 계정)은 암묵적으로 생략되었습니다.

해석해보겠습니다.

  • arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E36E6CTWWW86E5
    • CloudFront는 글로벌 서비스이기 때문에 리전 구분이 없습니다.
    • 서비스 식별자가 iam인 것 눈치채셨나요? 그런데 (AWS 계정)이 들어갈 자리에 cloudfront라고 되어있습니. 이것은 특별히 예약된 규칙입니다. CloudFront를 위해서 별도의 보안주체를 관리하는 리소스 그룹(user)이 있다는 것을 말해줍니다.
    • S3에 접근하는 E36E6CTWWW86E5라는 CloudFront 전용 보안주체를 가리킵니다. (S3와 CloudFront는 밀접한 관계)
  • arn:aws:s3:::mcas.musma.net/*
    • 서비스 식별자가 s3
    • S3의 경우 리소스 한정자는 곧 버킷을 나타냅니다.
      • 리소스 한정자 사용되는 리소스 그룹은 서비스 마다 다릅니다.
      • AWS 서비스에 사용되는 작업, 리소스 및 조건 키
      • 여기서 각 서비스 아래 ‘XX에서 정의한 리소스’ 항목을 보면 해당 서비스에서 사용할 수 있는 리소스 그룹(유형)이 나옵니다.
    • mcas.musma.net 버킷에 있는 모든 오브젝트를 가리킵니다.


그럼 이렇게 정리가 되겠지요.

S3 버킷 mcas.musma.net에 업로드된 모든 오브젝트를 읽을 권한(s3:GetObject)를 CloudFront Origin Access Identity E36E6CTWWW86E5에 부여한다.


리소스-기반 정책 특징

리소스-기반 정책이 자격증명-기반 정책과 어떻게 다른지 알아보았습니다.

주요 특징은 아무래도 Principal 속성이 들어간다는 것입니다. (이제 Principal만 봐도 구별하시겠지요?)

그리고 자격증명-기반 정책은 AWS IAM에서 직접 관리하지만, 리소스-기반 정책은 보통 위의 S3 예시처럼 해당 서비스의 리소스에서 자체적으로 관리합니다.


정책 유형 요약 비교

  자격증명-기반 정책(Id-Based Policy) 리소스-기반 정책(Resource-Based Policy)
연결 대상 사용자, 그룹, 역할 등
보안주체(Principal)가 될 수 있는 대상
리소스
의미 ( 이 정책이 연결된 보안주체는 )
( 특정 조건(Condition) 하에 )
이 리소스(Resource)에 대한
특정 행동(Action)을
허용/불허(Effect)
( 특정 조건(Condtion)하에 )
이 리소스(Resource)에 대한
특정 행동(Action)을
특정 보안주체(들)(Principal)에게
허용/불허(Effect)
특징1 Principal 속성이 안 들어감 Principal 속성이 들어감
특징2 IAM Policy 메뉴에서 관리
(혹은 IAM Role에 인라인으로)
일부 AWS 서비스의 리소스에서 자체 관리
(대표적으로 S3, SQS 등)
특징3 모든 AWS 서비스에 연관 일부 공유 자원 성격을 가진 서비스에서 사용
(대표적으로 S3, SQS 등)

어떤 서비스가 리소스-기반 정책을 사용할 수 있는지는 IAM로 작업하는 AWS 서비스를 참조하십시오.


[실습] 쪽지 시험

그냥 읽어보기만 했는데, 다 알아들은 것 같죠? 그것은 착각입니다.

Q. 아래 정책 예시를 보고 다음 물음에 답하시오.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:ListAllMyBuckets",
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
       ],
      "Resource": "arn:aws:s3:::mcas.musma.net"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::mcas.musma.net/*"
    }
  ]
}


1. 자격증명-기반 정책과 리소스-기반 정책 중 어떤 정책 유형인지 답하고 그 근거를 논하시오.

예시 답안

자격증명-기반 정책입니다.

각 Statement 마다 Principal 속성이 존재하지 않으므로 리소스-기반 정책이 아닙니다.


2. 동일한 서비스에 대해서 여러 Statement로 나누어서 선언한 이유를 논하시오.

예시 답안

각 서비스마다 고유의 리소스가 있습니다. 예를 들면 S3에서 특정할 수 있는 리소스는 버킷과 객체가 있습니다.

그리고 서비스의 액션 마다 대응하는 리소스 수준 권한이 다릅니다.

예를 들면 s3:GetObject, s3:PutObject, s3:DeleteObject는 객체에 대한 Action입니다. 따라서 대응하는 리소스의 수준도 객체 수준이어야 합니다. Resource 한정자로 arn:aws:s3:::mcas.musma.net/* (mcas.musma.net 버킷의 모든 객체)를 특정하고 있습니다.

s3:ListBucket, s3:GetBucketLocation은 버킷에 대한 Action입니다. 그래서 Resource 한정자로 mcas.mumsa.net 버킷을 가리키고 있습니다.

마지막으로, s3:ListAllMyBuckets는 S3에 딸린 특정 리소스를 한정하지 않는 서비스 수준의 Action입니다. 따라서 Resource를 "*"로 하였습니다.


Lessons Learned

이 글을 읽고 난 후에 여러분이 IAM Policy를 다시 보았을 때, 어지럼증이 조금 사라졌길 바랍니다.

여러분들 중에는 프로그래밍 실력만 믿고 클라우드 서비스에 무작정 덤볐다가, 예상 외로 많은 잡일(?)에 압도 당한 분들이 계실 겁니다. (그게 접니다.) 그냥 막 바로 쓰고 싶은데, 보안 그룹 만들어라, 역할 지정해라, 정책 생성해라, 어찌해라마라… 되게 까다롭습니다. 어렵고 귀찮습니다. 아무래도 이게 다, 새로운 것을 하면서도 공부도 안 하고 날로 먹으려고 했던 과오에서 비롯한게 아닌가 싶습니다.

무엇이든 처음에 낯설고 어려운 것은 당연한 것이니 공부를 해야겠지요. 그런데 어떤 공부는 다른 공부 보다 더 중요하고 우선해야 하는 것이 있습니다. 오늘 다룬 AWS IAM이 그런 것 같습니다. IAM을 외면하고 넘어가면 여러분이 새로운 서비스를 만날 때마다 괴로움을 겪게 될 것이고(…), 한 번 공부해서 기본 개념을 정리를 하고나면 (나중에 그때그때 노하우가 필요하겠지만) 좀 덜 어려울 수 있을 것입니다. (쉽지는 않다는…)

실천 사항

매일 IAM 사용 설명서를 한 절 씩 묵상하도록 합시다.


향후 과제

IAM Policy도 공부할 게 많지만, IAM Role도 녹록지 않습니다. 다음 번에 IAM Role도 같이 공부하도록 하겠습니다.

보안과 관련이 많은 Amazon Cognito와 AWS IoT 같은 서비스를 사용하면, IAM 정책을 만들고 관리해야 할 일이 다른 서비스를 사용할 때 보다 더 많습니다. 다음에는 권한 및 역할 위임에 관한 실무멀티-테넌트 환경에서 리소스를 공유하기 위해 IAM 정책을 사용하는 방법에 관해 알아보겠습니다.


References