카테고리 없음

Assume Role로 구현하는 AWS 교차 계정 권한 관리

sedong 2025. 4. 7. 09:35

AWS에서는 리소스 접근을 제어하기 위해 IAM(Identity and Access Management) 기능을 제공한다. 일반적으로 하나의 계정 내에서 사용자와 리소스를 관리할 수 있지만, 보안 요구사항이나 조직 구조에 따라 여러 AWS 계정을 사용하는 경우가 많다. 이럴 때 계정 간 자원 접근이 필요해지는 경우가 있다.

 

예를 들어, 보안이나 결제 목적으로 운영 계정과 개발 계정을 분리한 경우, 개발자가 운영 계정의 특정 리소스를 조회해야 할 수 있다. 또는 중앙 관리 계정에서 여러 계정의 리소스를 자동으로 점검하거나, 로깅/모니터링 시스템이 다양한 계정의 데이터를 수집해야 할 수도 있다.

이처럼 다른 AWS 계정의 리소스에 안전하게 접근해야 할 때 사용하는 것이 바로 Assume Role 기능이다. Assume Role 은 특정 계정에 존재하는 Role을 “신뢰할 수 있는 주체(Principal)“에게 위임하고, 상대 계정에서는 이를 Assume 하여 임시 자격 증명을 발급받아 작업한다.

 

보다 안전하고 유연하게 교차 계정 간의 권한을 설정하는 방법으로 AWS에서는STS(Security Token Service) 기반의 Assume Role 방식을 권장하고 있다.


Assume Role 이란?

AWS에서 IAM User는 고정된 자격 증명(Access Key, Secret Key)을 가지고 리소스에 접근한다. 반면에 IAM Role은 자격 증명이 없는 상태로 생성되며, 다른 주체가 해당 Role을 Assume 함으로써 임시로 권한을 획득하는 구조이다.

 

Assume Role은 두 개 이상의 계정이 연동되는 구조에서 사용된다. 한쪽에서는 역할(Role)을 생성하고, 어떤 주체가 해당 역할을 사용할 수 있는지를 설정한다. 이 역할은 신뢰할 수 있는 주체(Trusted Principal) 에 의해서만 사용이 가능하다. 다른 쪽에서는 이 Role을 AssumeRole API를 통해 사용하고, 임시 자격 증명을 발급받아 해당 계정의 리소스에 접근할 수 있게 된다. 여러 계정에서 공통 작업이 필요할 때, 가장 안전하고 권장되는 방식이 바로 이 Assume Role 구조이다.


Assume Role의 흐름

Assume Role은 기본적으로 **AWS Security Token Service(STS)**를 통해 동작한다. 사용자는 먼저 자신의 계정 자격 증명을 사용해 STS 클라이언트를 생성하고, 이 클라이언트를 통해 AssumeRole API를 호출한다. 이때 대상 Role의 ARN과 세션 이름을 함께 전달하면, AWS는 해당 Role이 허용한 신뢰 주체인지를 확인한 후 **임시 자격 증명(AccessKey, SecretKey, SessionToken)**을 발급한다.

 

이렇게 발급된 자격 증명은 일시적으로 유효하며, 이를 이용해 S3, EC2, DynamoDB 등의 서비스에 접근할 수 있다. 즉, 발급된 임시 자격을 사용해 새로운 세션을 구성하고, 이 세션으로 대상 계정의 리소스에 접근하는 방식이다.

 

이 과정의 핵심은, 원래의 고정된 자격 증명을 노출하지 않고도, 필요한 시점에만 제한된 권한을 가진 임시 자격을 부여받아 작업할 수 있다는 점이다. 이러한 흐름을 통해, 보안성과 유연성을 모두 확보한 교차 계정 접근이 가능해진다.


Assume Role의 장점

Assume Role은 단순히 계정 간 권한 위임을 위한 기능을 넘어, 보안성과 유연성을 동시에 확보할 수 있는 구조를 제공한다.

 

첫 번째로, 고정된 키를 공유하지 않아도 된다. IAM 사용자의 액세스 키처럼 영구적인 자격 증명을 사용하지 않고, Assume Role을 통해 매번 동적으로 임시 자격 증명을 발급받기 때문에 키 노출 위험이 줄어든다. 설령 유출되더라도 자격 증명은 일정 시간이 지나면 자동으로 만료되므로 보안성이 훨씬 높다.

 

두 번째는, 필요한 시점에만 자격을 사용할 수 있다는 점이다. Assume Role은 요청 시점에만 임시 자격이 발급되며, 그 외에는 아무 권한도 부여되지 않는다. 이를 통해 실제 사용이 필요한 순간에만 권한을 부여할 수 있어, **최소 권한 원칙(Least Privilege)**을 자연스럽게 구현할 수 있다.

 

세 번째로, 권한의 범위를 Role 단위로 제어할 수 있다는 장점이 있다. Assume Role로 접근하는 주체는 Role에 연결된 정책 범위 내에서만 작업이 가능하며, 대상 계정에서 허용한 리소스와 작업에 한정되기 때문에 **불필요한 권한 상승(Privilege Escalation)**을 방지할 수 있다.

 

마지막으로, 감사 추적이 용이하다는 점도 실무에서 매우 유용하다. Assume Role 요청 시 지정하는 RoleSessionName은 CloudTrail에 그대로 기록되며, 이를 통해 누가 언제 어떤 역할을 사용했는지를 명확히 추적할 수 있다. 보안 분석이나 감사 로그 검토가 필요한 환경에서 강력한 이점을 제공한다.

 

이러한 이유로 Assume Role은 단순한 기술 기능을 넘어, 보안성과 운영 효율을 모두 고려한 권한 위임 수단으로 사용된다.

 


AWS Assume Role

Assume Role 을 위한 권한 작업

A 계정에서는 접근을 요청하는 사용자 또는 시스템이 존재하고, B 계정에는 리소스를 소유한 주체가 있으며, 이 B 계정에서 역할(Role)을 생성한다.

 

먼저 B 계정에서 IAM Role을 생성해야 한다.

 

AWS 콘솔에서 IAM > Roles로 이동한 뒤, “Create role”을 클릭한다. 신뢰할 주체는 AWS 계정을 선택하고, 여기서 A 계정의 AWS Account ID를 입력한다. 이후 해당 Role에 필요한 권한을 부여한다. 예를 들어 S3 조회 권한만 필요한 경우에는 AmazonS3 ReadOnlyAccess 정책을 연결할 수 있다. Role 이름은 예를 들어 CrossAccountReadOnlyRole로 설정한다.

 

B 계정 AWS Console 에서 역할 생성

 

다음으로 A 계정의 사용자 또는 시스템에 권한을 부여해야 한다. 이 작업은 A 계정의 IAM 사용자 또는 IAM 그룹에 JSON 형식의 정책을 붙이는 방식으로 진행된다. 해당 정책은 sts:AssumeRole 액션을 허용해야 하며, 리소스로는 방금 B 계정에서 만든 Role의 ARN을 입력해야 한다.

 

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "sts:AssumeRole",
      "Resource": "arn:aws:iam::<B_ACCOUNT_ID>:role/CrossAccountReadOnlyRole"
    }
  ]
}

 

이제 A 계정 사용자는 AWS 콘솔에서 실제로 역할 전환(Switch Role)을 할 수 있다. 로그인 후 우측 상단 메뉴에서 Switch Role을 클릭하고, B 계정의 ID와 Role 이름을 입력하면 역할 전환이 가능하다. 전환이 완료되면 해당 Role에 부여된 권한만 사용할 수 있게 되며, 이를 통해 다른 계정의 리소스를 안전하게 다룰 수 있다.

 

AWS Conosle 상 역할 전환


Programming 방식

Python의 boto3 라이브러리를 사용하면 다음과 같이 코드를 통해 Role을 Assume 하고, 그 권한으로 리소스를 조회할 수 있다.

import boto3

# 기본 계정 자격 증명으로 STS 클라이언트 생성
sts_client = boto3.client('sts')

# Assume Role 수행
response = sts_client.assume_role(
    RoleArn="arn:aws:iam::<B_ACCOUNT_ID>:role/CrossAccountReadOnlyRole",
    RoleSessionName="example-session"
)

# 임시 자격 정보 추출
credentials = response['Credentials']

# 임시 자격으로 다른 서비스에 접근
s3_client = boto3.client(
    's3',
    aws_access_key_id=credentials['AccessKeyId'],
    aws_secret_access_key=credentials['SecretAccessKey'],
    aws_session_token=credentials['SessionToken']
)

# 접근 테스트: 예시로 버킷 리스트 조회
buckets = s3_client.list_buckets()
print([bucket['Name'] for bucket in buckets['Buckets']])

 

위 코드의 흐름은 다음과 같다:

  1. STS 클라이언트 생성
  2. AssumeRole API 호출로 임시 자격 발급
  3. 발급받은 자격 증명으로 새로운 세션 생성
  4. 대상 계정의 리소스에 접근

Assume Role 활용

Assume Role은 단순한 설정 외에도 실무에서 다양한 방식으로 활용될 수 있다.

 

우선, 역할 전환 시 지정하는 RoleSessionName은 단순히 세션 구분자 이상의 의미를 가진다. 이 이름은 CloudTrail 등의 로그에 기록되기 때문에, 역할을 누가 사용했는지를 명확히 추적하기 위해 실제 사용자 ID나 목적을 포함하는 형태로 구성하는 것이 좋다. 예를 들어 dev-to-prod-sync, cost-analyzer-bot 등과 같이 이름을 지정하면 운영 시 로그 분석에 도움이 된다.

 

또한 IAM 정책에는 조건(Condition)을 부여하여 더 세밀한 보안 제어가 가능하다. 예를 들어 MFA가 활성화된 사용자만 역할을 Assume 할 수 있도록 제한하거나, 특정 IP에서만 접근 가능하게 만들 수도 있다. 이러한 조건을 통해 보안적으로 접근할 수 있는 범위를 최소화할 수 있다.

 

Assume Role은 콘솔뿐만 아니라 CLI나 SDK에서도 동일하게 사용할 수 있다. AWS CLI에서는 sts assume-role 명령어를 사용하여 역할을 전환할 수 있으며, 반환된 결과에서 AccessKeyId, SecretAccessKey, SessionToken을 추출해 환경변수로 설정하면 된다. 이렇게 하면 다른 계정의 리소스를 CLI 상에서도 자유롭게 다룰 수 있다.

 

AWS에서 제공하는 IAM Policy Simulator를 활용하면 정책 충돌이나 누락된 권한을 사전에 테스트할 수 있다. 실무에서 Assume Role 설정 후 권한이 정상적으로 동작하지 않는 경우, 이 도구를 통해 빠르게 원인을 파악할 수 있다.