예제 4: 버킷 소유자가 소유하지 않은 객체에 계정 간 권한 부여하기

예제 4: 버킷 소유자가 소유하지 않은 객체에 계정 간 권한 부여하기 (Example 4 - Bucket owner granting cross-account permission to objects it does not own)

자신이 버킷을 소유하고 있고, 다른 AWS 계정이 객체를 업로드하도록 허용한 상황을 상상해 보세요. 버킷에 S3 Object Ownership의 버킷 소유자 적용(Bucket owner enforced) 설정을 적용했다면 다른 AWS 계정이 쓴 객체를 포함해 버킷 안의 모든 객체를 내가 소유해요. 이 방식은 객체가 버킷 소유자인 나의 소유가 아니라는 문제를 해결해요. 이제 자기 계정의 사용자나 다른 AWS 계정에 권한을 위임할 수 있어요. S3 Object Ownership의 버킷 소유자 적용 설정이 활성화되지 않았다고 가정해 볼게요. 그러면 버킷에는 다른 AWS 계정이 소유한 객체가 있을 수 있어요.

출처: 문서

본문

이제 버킷 소유자로서, 다른 계정의 사용자에게 객체에 대한 계정 간 권한을 부여해야 한다고 가정해 봐요. 누가 소유했는지는 관계없어요. 예를 들어 그 사용자는 객체 메타데이터에 접근해야 하는 결제(billing) 애플리케이션일 수 있어요. 여기에는 두 가지 핵심 문제가 있어요.

  • 버킷 소유자는 다른 AWS 계정이 만든 객체에 대한 권한이 없어요. 버킷 소유자가 소유하지 않은 객체에 권한을 부여하려면, 객체 소유자(객체를 만든 AWS 계정)가 먼저 버킷 소유자에게 권한을 부여해야 해요. 그런 다음 버킷 소유자가 그 권한을 위임할 수 있어요.
  • 버킷 소유자 계정은 자기 계정의 사용자에게 권한을 위임할 수 있어요(예제 3: 버킷 소유자가 소유하지 않은 객체에 권한 부여하기 참고). 하지만 계정 간 위임은 지원되지 않으므로 버킷 소유자 계정은 다른 AWS 계정에 권한을 위임할 수 없어요.

이 시나리오에서 버킷 소유자는 객체에 접근할 권한이 있는 AWS Identity and Access Management(IAM) 역할을 만들 수 있어요. 그런 다음 버킷 소유자는 다른 AWS 계정에 그 역할을 맡을(assume) 권한을 부여해, 그 계정이 일시적으로 버킷의 객체에 접근하도록 할 수 있어요.

참고 — S3 Object Ownership은 Amazon S3의 버킷 수준 설정으로, 버킷에 업로드된 객체의 소유권을 제어하고 ACL을 비활성화하거나 활성화하는 데 써요. 기본적으로 Object Ownership은 버킷 소유자 적용 설정이고, 모든 ACL은 비활성화돼 있어요. ACL이 비활성화되면 버킷 소유자가 버킷 안의 모든 객체를 소유하고 접근 관리 정책만으로 접근을 독점 관리해요. Amazon S3의 대부분의 현대 사용 사례는 더 이상 ACL이 필요 없어요. 객체마다 개별적으로 접근을 제어해야 하는 경우를 제외하고는 ACL을 비활성화해 두는 걸 권장해요. ACL이 비활성화되면 버킷에 누가 객체를 업로드했든 관계없이 정책으로 버킷의 모든 객체에 대한 접근을 제어할 수 있어요. 자세한 내용은 버킷의 객체 소유권 제어와 ACL 비활성화를 참고하세요.

계정 간 권한 이해와 IAM 역할 사용

IAM 역할은 여러 시나리오에서 리소스에 대한 접근을 위임할 수 있게 해주는데, 계정 간 접근이 핵심 시나리오 중 하나예요. 이 예제에서 버킷 소유자인 Account A는 IAM 역할을 사용해 객체 접근을 다른 AWS 계정인 Account C의 사용자에게 일시적으로 계정 간 위임해요. 만든 각 IAM 역할에는 다음 두 가지 정책이 연결돼 있어요.

  • 역할을 맡을 수 있는 다른 AWS 계정을 식별하는 신뢰 정책(trust policy)
  • 누군가 역할을 맡았을 때 허용되는 권한(예: s3:GetObject)을 정의하는 접근 정책(access policy)

정책에 지정할 수 있는 권한 목록은 Amazon S3의 정책 작업을 참고하세요.

신뢰 정책에서 식별된 AWS 계정은 그 후 사용자에게 역할을 맡을 권한을 부여해요. 사용자는 다음 단계로 객체에 접근할 수 있어요.

  1. 역할을 맡고, 그 응답으로 임시 보안 자격 증명을 얻어요.
  2. 임시 보안 자격 증명을 사용해 버킷의 객체에 접근해요.

IAM 역할에 대한 자세한 내용은 IAM User Guide의 IAM 역할을 참고하세요.

이 연습의 단계를 요약하면 다음과 같아요.

  • Account A 관리자 사용자가 버킷 정책을 연결해 Account B에 객체를 조건부로 업로드할 권한을 부여해요.
  • Account A 관리자가 IAM 역할을 만들어 Account C와 신뢰 관계를 맺어, 그 계정의 사용자가 Account A에 접근할 수 있게 해요. 역할에 연결된 접근 정책은 Account C의 사용자가 Account A에 접근할 때 무엇을 할 수 있는지 제한해요.
  • Account B 관리자가 Account A가 소유한 버킷에 객체를 업로드하고 버킷 소유자에게 전체 제어 권한을 부여해요.
  • Account C 관리자가 사용자를 만들고, 그 사용자가 역할을 맡을 수 있게 하는 사용자 정책을 연결해요.
  • Account C의 사용자가 먼저 역할을 맡아 임시 보안 자격 증명을 받아요. 그 임시 자격 증명으로 사용자가 버킷의 객체에 접근해요.

이 예제를 진행하려면 계정이 세 개 필요해요. 다음 표는 이 계정들과 그 안의 관리자 사용자를 어떻게 부를지 보여줘요. IAM 지침(리소스 생성과 권한 부여를 위한 관리자 사용자에 대해)에 따라 이 연습에서는 AWS 계정 루트 사용자 자격 증명을 사용하지 않아요. 대신 각 계정에 관리자 사용자를 만들고 그 자격 증명으로 리소스를 만들고 권한을 부여해요.

AWS 계정 ID 계정 표기 계정의 관리자 사용자
1111-1111-1111 Account A AccountAadmin
2222-2222-2222 Account B AccountBadmin
3333-3333-3333 Account C AccountCadmin

0단계: 연습 준비하기

참고 — 텍스트 편집기를 열고 단계를 진행하면서 일부 정보를 적어 두는 게 좋아요. 특히 각 계정의 계정 ID, 정규 사용자 ID, 콘솔에 연결하기 위한 IAM 사용자 로그인 URL, IAM 사용자와 역할의 Amazon 리소스 이름(ARN)이 필요해요.

세 개의 AWS 계정이 있고, 앞 절의 표처럼 각 계정에 관리자 사용자가 하나씩 있는지 확인하세요.

  1. 필요하면 AWS 계정에 가입해요. 이 계정들을 Account A, Account B, Account C라고 부를게요.
  2. Account A 자격 증명으로 IAM 콘솔에 로그인해서 관리자 사용자를 만들어요.
    • 사용자 AccountAadmin을 만들고 보안 자격 증명을 기록해 두세요. 사용자 추가에 대한 자세한 내용은 IAM User Guide의 AWS 계정에 IAM 사용자 만들기를 참고하세요.
    • 전체 액세스를 주는 사용자 정책을 연결해 AccountAadmin에게 관리자 권한을 부여해요. 자세한 방법은 IAM User Guide의 IAM 정책 관리를 참고하세요.
    • IAM 콘솔 대시보드에서 IAM 사용자 로그인 URL(Sign-In URL) 을 기록해 두세요. 이 계정의 사용자는 AWS Management Console에 로그인할 때 이 URL을 사용해야 해요. 자세한 내용은 IAM User Guide의 IAM 사용자로 AWS Management Console에 로그인을 참고하세요.
  3. 앞의 단계를 반복해 Account B와 Account C에 관리자 사용자를 만들어요.
  4. Account C의 정규 사용자 ID를 기록해 두세요.

Account A에서 IAM 역할을 만들 때 신뢰 정책은 계정 ID를 지정해 Account C에 역할을 맡을 권한을 부여해요. 계정 정보는 다음과 같이 찾을 수 있어요.

  1. AWS 계정 ID나 계정 별칭, IAM 사용자 이름, 비밀번호를 사용해 Amazon S3 콘솔에 로그인해요.
  2. Amazon S3 버킷 이름을 선택해 그 버킷에 대한 세부 정보를 봐요.
  3. 권한(Permissions) 탭을 선택한 다음 Access Control List를 선택해요.
  4. 내 AWS 계정 액세스(Access for your AWS account) 섹션의 계정(Account) 열에 c1daexampleaaf850ea79cf0430f33d72579fd1611c97f7ded193374c0b163b6 같은 긴 식별자가 있어요. 이것이 정규 사용자 ID예요.

버킷 정책을 만들 때 다음 정보가 필요해요. 이 값을 기록해 두세요.

  • Account A의 정규 사용자 ID — Account A 관리자가 Account B 관리자에게 조건부 객체 업로드 권한을 부여할 때, 그 조건은 객체에 대해 전체 제어를 받아야 하는 Account A 사용자의 정규 사용자 ID를 지정해요. 참고로 정규 사용자 ID는 Amazon S3 전용 개념이에요. 계정 ID를 난독화한 64자 값이에요.
  • Account B 관리자의 사용자 ARN — 사용자 ARN은 IAM 콘솔에서 찾을 수 있어요. 사용자를 선택하고 요약(Summary) 탭에서 사용자의 ARN을 찾아야 해요. 버킷 정책에서 AccountBadmin에게 객체 업로드 권한을 부여할 때 사용자를 ARN으로 지정해요. 예제 ARN 값은 다음과 같아요: arn:aws:iam::AccountB-ID:user/AccountBadmin
  1. AWS Command Line Interface(AWS CLI) 또는 AWS Tools for Windows PowerShell을 설정해요. 관리자 사용자 자격 증명을 다음과 같이 저장하세요.
    • AWS CLI를 사용한다면 config 파일에 AccountAadmin과 AccountBadmin 프로필을 만들어요.
    • AWS Tools for Windows PowerShell을 사용한다면 세션에 AccountAadmin과 AccountBadmin으로 자격 증명을 저장해요.
    • 자세한 방법은 연습을 위한 도구 설정을 참고하세요.

1단계: Account A 작업 수행하기

이 예제에서 Account A는 버킷 소유자예요. 그래서 Account A의 AccountAadmin 사용자가 다음을 수행해요.

  • 버킷을 만들어요.
  • Account B 관리자에게 객체 업로드 권한을 부여하는 버킷 정책을 연결해요.
  • Account C에 역할을 맡을 권한을 부여하는 IAM 역할을 만들어, Account C가 버킷의 객체에 접근할 수 있게 해요.

1.1단계: AWS Management Console에 로그인하기

Account A의 IAM 사용자 로그인 URL을 사용해 먼저 AWS Management Console에 AccountAadmin 사용자로 로그인해요. 이 사용자가 버킷을 만들고 정책을 연결할 거예요.

1.2단계: 버킷을 만들고 버킷 정책 연결하기

Amazon S3 콘솔에서 다음을 수행해요.

  1. 버킷을 만들어요. 이 연습에서는 버킷 이름이 amzn-s3-demo-bucket1이라고 가정해요. 자세한 방법은 일반용 버킷 만들기를 참고하세요.
  2. 다음 버킷 정책을 연결하세요. 이 정책은 Account B 관리자에게 객체 업로드 조건부 권한을 부여해요.

amzn-s3-demo-bucket1, AccountB-ID, CanonicalUserId-of-AWSaccountA-BucketOwner 자리에 자신의 값을 넣어 정책을 업데이트하세요.

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "111",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:user/AccountBadmin"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*"
        },
        {
            "Sid": "112",
            "Effect": "Deny",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:user/AccountBadmin"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*",
            "Condition": {
                "StringNotEquals": {
                    "s3:x-amz-grant-full-control": "id=CanonicalUserId-of-AWSaccountA-BucketOwner"
                }
            }
        }
    ]
}

1.3단계: Account A에서 Account C의 계정 간 접근을 허용하는 IAM 역할 만들기

IAM 콘솔에서 Account C에 역할을 맡을 권한을 부여하는 IAM 역할(examplerole)을 만들어요. 역할은 Account A에서 만들어야 하므로 여전히 Account A 관리자로 로그인해 있는지 확인하세요.

역할을 만들기 전에, 역할에 필요한 권한을 정의하는 관리형 정책을 준비해요. 이 정책은 나중에 역할에 연결할 거예요.

  1. 왼쪽 탐색 창에서 정책(Policies) 을 선택한 다음 정책 만들기(Create Policy) 를 선택해요.
  2. 직접 정책 만들기(Create Your Own Policy) 옆에서 선택(Select) 을 선택해요.
  3. 정책 이름(Policy Name) 필드에 access-accountA-bucket을 입력해요.
  4. 다음 접근 정책을 복사해 정책 문서(Policy Document) 필드에 붙여넣어요. 이 접근 정책은 역할에 s3:GetObject 권한을 부여해서, Account C 사용자가 역할을 맡으면 s3:GetObject 작업만 수행할 수 있게 해요.
{
  "Version":"2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::amzn-s3-demo-bucket1/*"
    }
  ]
}
  1. 정책 만들기(Create Policy) 를 선택해요. 새 정책이 관리형 정책 목록에 나타나요.
  2. 왼쪽 탐색 창에서 역할(Roles) 을 선택한 다음 새 역할 만들기(Create New Role) 를 선택해요.
  3. 역할 유형 선택(Select Role Type) 아래에서 계정 간 액세스용 역할(Role for Cross-Account Access) 을 선택한 다음, 소유한 AWS 계정 간 액세스 제공(Provide access between AWS accounts you own) 옆의 선택(Select) 버튼을 선택해요.
  4. Account C의 계정 ID를 입력해요. 이 연습에서는 사용자가 역할을 맡기 위해 다중 인증(MFA)을 요구할 필요가 없으니 그 옵션은 선택하지 말아요.
  5. 다음 단계(Next Step) 를 선택해 역할과 연결할 권한을 설정해요.
  6. 만든 access-accountA-bucket 정책 옆의 확인란을 선택한 다음 다음 단계(Next Step) 를 선택해요.
  7. 검토(Review) 페이지에서 역할 설정을 확인해요. 이 페이지에서 주의할 아주 중요한 항목이 하나 있어요. 이 역할을 사용해야 하는 사용자에게 보낼 수 있는 링크예요. 그 링크를 사용하는 사용자는 계정 ID와 역할 이름 필드가 이미 채워진 역할 전환(Switch Role) 페이지로 바로 이동해요. 이 링크는 나중에 계정 간 역할의 역할 요약(Role Summary) 페이지에서도 볼 수 있어요.
  8. 역할 이름에 examplerole을 입력하고 다음 단계(Next Step) 를 선택해요.
  9. 역할을 검토한 후 역할 만들기(Create Role) 를 선택해요. examplerole 역할이 역할 목록에 표시돼요.
  10. 역할 이름 examplerole을 선택해요.
  11. 신뢰 관계(Trust Relationships) 탭을 선택해요.
  12. 정책 문서 표시(Show policy document) 를 선택하고 표시된 신뢰 정책이 다음 정책과 일치하는지 확인해요.

다음 신뢰 정책은 sts:AssumeRole 작업을 허용해 Account C와 신뢰 관계를 맺어요. 자세한 내용은 AWS Security Token Service API Reference의 AssumeRole을 참고하세요.

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::111122223333:root"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
  1. 만든 examplerole 역할의 Amazon 리소스 이름(ARN)을 기록해 두세요. 이후 단계에서 IAM 사용자가 이 역할을 맡도록 하는 사용자 정책을 연결할 때 역할을 ARN 값으로 식별해요.

2단계: Account B 작업 수행하기

Account A가 소유한 예제 버킷에는 다른 계정이 소유한 객체가 필요해요. 이 단계에서 Account B 관리자는 명령줄 도구로 객체를 업로드해요.

put-object AWS CLI 명령으로 amzn-s3-demo-bucket1에 객체를 업로드해요.

aws s3api put-object --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg --body HappyFace.jpg --grant-full-control id="canonicalUserId-ofTheBucketOwner" --profile AccountBadmin

다음 사항을 주목하세요.

  • --Profile 파라미터가 AccountBadmin 프로필을 지정하므로, 객체는 Account B가 소유해요.
  • grant-full-control 파라미터는 버킷 정책에서 요구하는 대로 버킷 소유자에게 객체의 전체 제어 권한을 부여해요.
  • --body 파라미터는 업로드할 소스 파일을 가리켜요. 예를 들어 Windows 컴퓨터의 C 드라이브에 파일이 있다면 c:\HappyFace.jpg라고 지정해요.

3단계: Account C 작업 수행하기

앞의 단계에서 Account A는 이미 Account C와 신뢰 관계를 맺는 역할 examplerole을 만들었어요. 이 역할은 Account C의 사용자가 Account A에 접근할 수 있게 해줘요. 이 단계에서 Account C 관리자는 사용자(Dave)를 만들고 Account A로부터 받은 sts:AssumeRole 권한을 그에게 위임해요. 이 방식으로 Dave는 examplerole을 맡아 일시적으로 Account A에 접근할 수 있어요. Account A가 역할에 연결한 접근 정책은 Dave가 Account A에 접근할 때 무엇을 할 수 있는지 제한해요. 구체적으로 amzn-s3-demo-bucket1의 객체를 가져오는 것이에요.

3.1단계: Account C에 사용자를 만들고 examplerole을 맡을 권한 위임하기

  1. Account C의 IAM 사용자 로그인 URL을 사용해 먼저 AWS Management Console에 AccountCadmin 사용자로 로그인해요.
  2. IAM 콘솔에서 사용자 Dave를 만들어요. 단계별 안내는 IAM User Guide의 IAM 사용자 만들기(AWS Management Console)를 참고하세요.
  3. Dave의 자격 증명을 기록해 두세요. Dave는 이 자격 증명으로 examplerole 역할을 맡아야 해요.
  4. Dave IAM 사용자에게 Account A의 examplerole 역할에 대한 sts:AssumeRole 권한을 위임하는 인라인 정책을 만들어요.
    • 왼쪽 탐색 창에서 사용자(Users) 를 선택해요.
    • 사용자 이름 Dave를 선택해요.
    • 사용자 세부 정보 페이지에서 권한(Permissions) 탭을 선택하고 인라인 정책(Inline Policies) 섹션을 펼쳐요.
    • 여기를 클릭(click here) (또는 사용자 정책 만들기(Create User Policy))를 선택해요.
    • 사용자 지정 정책(Custom Policy) 을 선택한 다음 선택(Select) 을 선택해요.
    • 정책 이름(Policy Name) 필드에 정책 이름을 입력해요.
    • 다음 정책을 정책 문서(Policy Document) 필드에 복사해 붙여넣어요.

AccountA-ID를 제공하도록 정책을 업데이트해야 해요.

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sts:AssumeRole"
            ],
            "Resource": "arn:aws:iam::111122223333:role/examplerole"
        }
    ]
}
  1. 정책 적용(Apply Policy) 을 선택해요.
  2. 또 다른 프로필 AccountCDave를 추가해 Dave의 자격 증명을 AWS CLI의 config 파일에 저장해요.
[profile AccountCDave]
aws_access_key_id = UserDaveAccessKeyID
aws_secret_access_key = UserDaveSecretAccessKey
region = us-west-2

3.2단계: 역할 맡기(examplerole)와 객체 접근하기

이제 Dave는 다음과 같이 Account A가 소유한 버킷의 객체에 접근할 수 있어요.

  1. Dave는 먼저 자신의 자격 증명으로 examplerole을 맡아요. 이렇게 하면 임시 자격 증명이 반환돼요.

  2. Dave는 그 임시 자격 증명을 사용해 Account A 버킷의 객체에 접근해요.

  3. 명령 프롬프트에서 AccountCDave 프로필로 다음 AWS CLI assume-role 명령을 실행해요.

examplerole이 정의된 AccountA-ID를 제공하도록 명령의 ARN 값을 업데이트해야 해요.

aws sts assume-role --role-arn arn:aws:iam::AccountA-ID:role/examplerole --profile AccountCDave --role-session-name test
  1. 응답으로 AWS Security Token Service(AWS STS)가 임시 보안 자격 증명(액세스 키 ID, 비밀 액세스 키, 세션 토큰)을 반환해요.
  2. 임시 보안 자격 증명을 AWS CLI config 파일의 TempCred 프로필 아래에 저장해요.
[profile TempCred]
aws_access_key_id = temp-access-key-ID
aws_secret_access_key = temp-secret-access-key
aws_session_token = session-token
region = us-west-2
  1. 명령 프롬프트에서 다음 AWS CLI 명령을 실행해 임시 자격 증명으로 객체에 접근해요. 예를 들어 이 명령은 head-object API를 지정해 HappyFace.jpg 객체의 메타데이터를 검색해요.
aws s3api get-object --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg SaveFileAs.jpg --profile TempCred
  1. examplerole에 연결된 접근 정책이 이 작업을 허용하므로 Amazon S3가 요청을 처리해요. 버킷의 다른 객체에서도 다른 작업을 시도할 수 있어요.
  2. 다른 작업(예: get-object-acl)을 시도하면 역할이 그 작업을 허용하지 않으므로 권한 거부가 나와요.
aws s3api get-object-acl --bucket amzn-s3-demo-bucket1 --key HappyFace.jpg --profile TempCred

우리는 사용자 Dave로 역할을 맡아 임시 자격 증명으로 객체에 접근했어요. 이 대신 Account C의 애플리케이션이 amzn-s3-demo-bucket1의 객체에 접근하는 경우도 있을 수 있어요. 애플리케이션은 임시 보안 자격 증명을 얻을 수 있고, Account C는 애플리케이션에 examplerole을 맡을 권한을 위임할 수 있어요.

4단계: 정리하기

테스트가 끝나면 다음 단계로 정리할 수 있어요.

  1. Account A 자격 증명으로 AWS Management Console에 로그인해서 다음을 수행하세요.
    • Amazon S3 콘솔에서 amzn-s3-demo-bucket1에 연결된 버킷 정책을 제거해요. 버킷 속성(Properties) 의 권한(Permissions) 섹션에서 정책을 삭제해요.
    • 이 연습을 위해 만든 버킷이라면 Amazon S3 콘솔에서 객체를 삭제한 다음 버킷을 삭제해요.
    • IAM 콘솔에서 Account A에서 만든 examplerole을 제거해요. 단계별 안내는 IAM User Guide의 IAM 사용자 삭제를 참고하세요.
    • IAM 콘솔에서 AccountAadmin 사용자를 제거해요.
  2. Account B 자격 증명으로 IAM 콘솔에 로그인해서 사용자 AccountBadmin을 삭제해요.
  3. Account C 자격 증명으로 IAM 콘솔에 로그인해서 AccountCadmin과 사용자 Dave를 삭제해요.

관련 리소스

이 연습과 관련된 자세한 내용은 IAM User Guide의 다음 리소스를 참고하세요.

더 알아보기 (Learn more)