AWS STS (AWS Security Token Service)
STS는 임시 보안 자격 증명을 위한 서비스입니다. STS를 활용하여 현재 자신이 사용하고 있는 자격을 알아내거나, 다른 user, role에 대한 자격 증명을 받아서 사용할 수도 있습니다. 아래는 현재 적용 중인 자격 증명을 알아내는 AWS CLI 명령어입니다.
$ aws sts get-caller-identity
{
"UserId": "AROAYUN3EWXKCUQU5HSO2:eks-role",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/admin/instance-id"
}
Demo
STS에서는 Assume Role이란 기능으로 임시 자격 증명을 받을 수 있습니다. 이를 위해 example-s3-buc에 접근할 수 있는 Role인 RoleB와 RoleB에 대해 assume role 권한이 있는 role인 RoleA를 생성해 보겠습니다.
example-s3-buc bucket policy
{
"Version": "2012-10-17",
"Id": "Policy1672054741842",
"Statement": [
{
"Sid": "Stmt1672054738314",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/RoleB"
},
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::example-s3-buc/*",
"arn:aws:s3:::example-s3-buc"
]
}
]
}
RoleA
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
RoleB의 신뢰 관계에서 RoleA에 대한 Assume Role을 허용해주기 때문에 기본상태 그대로인 모습입니다. 생성할 때 ec2가 사용할 거라고 선택한다면 인스턴스에서 자격 증명을 사용해야 하기 때문에 ec2 Service에 대한 assume role을 default값으로 허용하는 모습을 볼 수 있습니다.
RoleB
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com",
"AWS": "arn:aws:iam::593634833876:role/RoleA"
},
"Action": "sts:AssumeRole"
}
]
}
그리고 테스트용 텍스트 파일을 만들어 s3에 넣어두겠습니다.
cat << EOF > test.txt
Test Text
EOF
먼저 RoleA가 붙은 instance로 S3를 조회해 보겠습니다.
$ aws sts get-caller-identity
{
"UserId": "AROAYUN3EWXKCRZILAD47:i-0dba4c336e406dca7",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/RoleA/i-0dba4c336e406dca7"
}
$ aws s3 cp s3://example-s3-buc/test.txt ./
fatal error: An error occurred (403) when calling the HeadObject operation: Forbidden
액세스가 거부되어 에러를 뱉는 모습입니다.
이제 sts를 통해 RoleB를 수임해서 s3를 이용해보도록 하겠습니다. 먼저 아래 명령어를 통해 RoleB의 AccessKey, SecretAccessKey, SessionToken을 받아줍시다.
$ aws sts assume-role --role-arn arn:aws:iam::111111111111:role/RoleB --role-session-name RoleB
{
"Credentials": {
"AccessKeyId": "ASIAYUN3EWXKO3V2LQMI",
"SecretAccessKey": "TOoszw....",
"SessionToken": "IQoJb3JpZ2lu...qEKGDlkEwrZZ",
"Expiration": "2022-12-27T03:40:50+00:00"
},
"AssumedRoleUser": {
"AssumedRoleId": "AROAYUN3EWXKDQQGZ7EX3:RoleB",
"Arn": "arn:aws:sts::111111111111:assumed-role/RoleB/RoleB"
}
}
그렇게 받아온 토큰을 아래와 같이 적용시켜 줍니다.
export AWS_ACCESS_KEY_ID={ACCESS_KEY}
export AWS_SECRET_ACCESS_KEY={SECRET_ACCESS_KEY}
export AWS_SESSION_TOKEN={SESSION_TOKEN}
그 후 aws cli를 통해 IAM을 확인해보면 RoleB로 역할이 전환되어있는 모습을 볼 수 있습니다.
$ aws sts get-caller-identity
{
"UserId": "AROAYUN3EWXKDWDAZ7EX3:RoleB",
"Account": "111111111111",
"Arn": "arn:aws:sts::111111111111:assumed-role/RoleB/RoleB"
}
바뀐 역할로 s3에서 객체를 복사해보면 RoleB로 접근되어 S3의 신뢰 정책(AWS S3 Trust Policies)에 걸리지 않아 요청이정상적으로 수행되는 모습을 볼 수 있습니다.
$ aws s3 cp s3://example-s3-buc/test.txt ./ && cat test.txt
download: s3://example-s3-buc/test.txt to ./test.txt
Test Text
이렇게 생성된 토큰은 3600초(1시간) 동안 유효합니다. 이러한 유효시간(Duration Seconds)은 다음과 같은 플래그를 통해 최소 900초(15분)에서 최대 43200초(12시간)까지 지정할 수 있습니다.
$ aws sts assume-role --role-arn arn:aws:iam::111111111111:role/RoleB --role-session-name RoleB
--duration-seconds {SECONDS}