AWS Credential 알아보기

연어코·2026년 1월 11일

기술 탐구

목록 보기
5/5
post-thumbnail

AWS 보안 인증을 이해하여 프로젝트 설계에 활용할 목적으로 작성합니다.

1. AWS IAM

User

User는 AWS 계정에서 생성할 수 있는 엔터티입니다.

User는 인간 사용자 또는 워크로드(애플리케이션)를 나타냅니다.

예를 들어 User는 아래와 같이 AWS 리소스와 상호작용할 수 있습니다.

  • 인간 사용자는 콘솔(웹 UI)에서 비밀번호로 로그인
  • 애플리케이션은 API/CLI에서 Access Key로 호출

User는 이름 및 자격 증명(콘솔 비밀번호, Access Key 등)으로 구성되어 있습니다.

사용자 식별

User 이름은 AWS 리소스 이름(ARN)에 표시됩니다. ARN은 로그, 정책, 에러 메시지 등에 노출될 수 있습니다. 따라서 User 이름에 개인 식별 정보(실명, 이메일 등)를 포함하지 않는 것을 권장합니다.

예를 들어 ARN은 아래와 같이 나타납니다.

arn:aws:iam::account-ID-without-hyphens:user/user-name
arn:aws:iam::887926046480:user/developer-01

AWS에서 사용자를 식별할 때는 User 이름, ARN, User ID를 사용할 수 있습니다.

Role

Role은 특정 권한을 지닌 엔터티입니다.

위에서 말했던 User도 여러 개의 Role을 assume할(맡을) 수 있습니다. 예를 들어 developer-01이라는 User가 상황에 따라 관리자 Role 또는 개발자 Role을 assume할 수 있습니다.

Role에는 권한이 정의된 Policy를 연결할 수 있습니다. 예를 들어 개발자 Role에 AmazonS3FullAccess Policy와 AmazonEC2FullAccess Policy를 연결할 수 있습니다.

보안 인증

Role은 User와 달리 콘솔 비밀번호, Access Key와 같은 장기 자격 증명이 없습니다.

대신 assume 시 임시 자격 증명이 발급됩니다. 보안상의 이유로 Role을 맡아 임시로 자격 증명을 생성하는 방식입니다. (Assume Role 방식)

여기서 임시 자격 증명은 다음과 같이 구성됩니다.

  • 임시 Access Key (Access Key Id + Secret Access Key)
  • Session Token
  • 만료 시간

User의 장기 자격 증명은 만료되지 않기에 노출 시 보안 위험이 있습니다. 따라서 Role을 assume하여 AWS 리소스에 접근하는 것이 권장됩니다.

⚠️ IAM 모범 사례는 임시 자격 증명으로 보안 인증하는 것입니다.
그 외 불가피한 경우 IAM User의 장기 자격 증명을 사용합니다.

⚠️ 장기 자격 증명을 사용하기로 한 경우 애플리케이션 코드에 Access Key를 직접 포함하지 마세요.
프론트엔드에서 환경변수로 관리하면 브라우저에 노출됩니다.
대신 서버에 환경변수로 관리하고, 정기적으로 키를 로테이션합니다.

Policy

Policy는 권한을 정의한 문서입니다. 아래와 같이 JSON 형식으로 작성됩니다.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow", // 액세스 허용/거부 여부 지정
      "Principal": {}, // (일부 상황에서 필요)
      "Action": [], // 작업 목록
      "Resource": [], // (일부 상황에서 필요)
      "Condition": {}, // (선택 사항)
      // ...
    }
  ]
}

Policy의 종류는 다음과 같습니다.

  • Identity-based Policy
  • Resource-based Policy
  • Trust Policy

Identity-based Policy는 User, Group 또는 Role에 연결됩니다.

Resource-based Policy는 AWS 리소스에 연결됩니다.

Trust Policy는 Role에 연결되며, 누가(어떤 Principal이) 해당 Role을 assume할 수 있는지 정의합니다.

Effect

Effect는 Allow 혹은 Deny 중 하나를 지정합니다.

기본적으로 리소스 액세스는 거부됩니다. 리소스 액세스를 허용하려면 Effect를 Allow로 지정해야 합니다.

"Effect": "Allow"

Principal

Principal은 리소스에 접근하거나 Role을 assume할 수 있는 주체를 지정합니다.

Principal은 Resource-based Policy와 Trust Policy에만 있습니다.

// IAM User
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:user/user-name" }
// AWS Role
"Principal": { "AWS": "arn:aws:iam::AWS-account-ID:role/role-name" }
// AWS Service
"Principal": {
    "Service": [
        "ecs.amazonaws.com",
        "elasticloadbalancing.amazonaws.com",
        "rolesanywhere.amazonaws.com"
   ]
}
// OIDC Federation
"Principal": { "Federated": "arn:aws:iam::AWS-account-ID:oidc-provider/full-OIDC-identity-provider-URL" }

Action

Action은 Allow 또는 Deny할 특정 작업을 지정합니다.

Policy statement에는 Action 또는 NotAction 요소가 반드시 추가되어야 합니다.

작업 값은 접두사인 서비스 네임페이스(iam, s3, ec2, sqs 등)와 작업 이름으로 구성됩니다.

"Action": [ 
  "iam:ChangePassword", 
  "s3:GetObject",
  "ec2:StartInstances", 
  "sqs:SendMessage", 
  "sqs:ReceiveMessage"
]

Resource

Resource는 statement의 적용 대상인 AWS 리소스를 정의합니다.

statement에는 Resource 또는 NotResource 요소가 반드시 추가되어야 합니다.

// AWS S3 버킷 내에 포함된 모든 항목 지정
"Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"

Condition

Condition은 Policy의 효력이 발생할 시점을 지정합니다.

// john이 요청할 때만 효력 발생
"Condition" : { "StringEquals" : { "aws:username" : "john" }}
// Condition 요소에 지정된 Principal을 제외한 모든 Principal을 거부
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Sid": "UsePrincipalArnInsteadOfNotPrincipalWithDeny",
      "Effect": "Deny",
      "Action": "s3:*",
      "Principal": "*",
      "Resource": [
        "arn:aws:s3:::amzn-s3-demo-bucket/*",
        "arn:aws:s3:::amzn-s3-demo-bucket"
      ],
      "Condition": {
        "ArnNotEquals": {
          "aws:PrincipalArn": "arn:aws:iam::444455556666:user/user-name"
        }
      }
    }
  ]
}

2. IAM Roles Anywhere

IAM Roles Anywhere은 외부 애플리케이션에서 임시 자격 증명으로 AWS 리소스에 접근하기 위한 서비스입니다.

앞서 장기 자격 증명으로 인증하면 보안에 좋지 못하다고 했습니다. 그럼 어떻게 하는 게 나을까요? Assume Role 방식으로 할 수 있습니다. 즉 Role을 맡아서 임시 자격 증명을 제공할 수 있습니다.

여기서 AWS 리소스에 접근하는 주체는 인간 사용자가 아니라 외부 애플리케이션입니다.

AWS 외부에서 실행되는 애플리케이션은 AWS 자격 증명을 직접 가질 수 없기 때문에 별도의 신원 확인 방법이 필요합니다. 이때 신원을 확인하는 방법 중 하나가 Roles Anywhere입니다. 신원 확인이 되면 외부 애플리케이션에서도 임시 자격 증명을 발급하여 AWS 리소스에 접근할 수 있게 되는 것이죠.

신원 확인

그럼 어떻게 신원을 확인할 수 있을까요?

Roles Anywhere은 인증서 방식을 사용합니다. (X.509 인증서)

예를 들어 내가(외부 애플리케이션이) 주점에 가서 음식을 먹는 상황을 상상해 봅시다. 주민등록증을 내밀어야겠죠. 주점은 Roles Anywhere입니다. 주민등록증은 클라이언트 인증서입니다. 주민등록증 안에 찍힌 지문은 공개키이고, 내가 가진 지문은 개인키입니다. 이러한 주민등록증이 유효한 이유는 주민등록증에 찍힌 정부 직인(CA 서명) 때문입니다. 정부에선 CA 인증서를 저장하고 있기에 신원 확인이 가능합니다.

1) 인증서 준비

외부 애플리케이션이 개인키와 공개키 쌍을 생성합니다.

그리고 공개키를 CA에 제출하여 클라이언트 인증서(안에 공개키 + CA 서명이 있음)를 발급받습니다.

2) AWS 계정 설정

사용자는 자신의 AWS 계정에서 Trust Anchor로 CA 인증서를 등록해야 합니다.

그리고 Assume Role 방식으로 임시 자격 증명을 받기 위해 Role을 생성합니다. Role에 Trust Policy를 연결할 때 Principal을 "Service": "rolesanywhere.amazonaws.com"으로 설정합니다. Condition으로 위에서 등록한 Trust Anchor ARN이 일치할 때만 효력이 발생하도록 합니다.

AWS 계정에 Profile도 생성해야 하는데요, Profile은 어떤 Role을 assume할 수 있는지 정의하고, 세션 정책 등 추가 제한을 설정합니다. 위에서 등록한 Trust Anchor와 Role을 연결하여 Profile을 생성합니다.

3) 임시 자격 증명 발급

이제 개인키로 서명한 요청 + 인증서 + Role ARN + Trust Anchor ARN + Profile ARN으로 Roles Anywhere 서비스를 호출합니다. 그 결과 외부 애플리케이션이 임시 자격 증명을 발급받아 AWS 리소스에 접근할 수 있게 됩니다.

3. Identity Provider

앞서 IAM Roles Anywhere 방식이 조금 까다로웠는데요, 외부 애플리케이션에서 임시 자격 증명을 받기 위한 좀 더 간단한 방법은 없을까요?

임시 자격 증명을 위한 두 번째 방법으로 Identity Provider 방법이 있습니다.

Identity Provider에는 OIDC Provider, SAML Provider가 있습니다.

OIDC 및 OAuth 2.0

이미 OIDC Identity Provider에는 GitHub, Google, AWS Cognito 등이 있습니다.

OIDC (OpenID Connect)는 GitHub과 같은 AWS 외부 애플리케이션을 AWS 리소스에 연결합니다.

GitHub Actions처럼 외부 애플리케이션에서 사용자의 AWS 리소스에 접근해야 하는 상황을 가정해 봅시다. (GitHub에 코드를 푸시하기만 하면 내 코드가 AWS ECR에 배포된다고 해봅시다.)

이때 GitHub에 사용자의 AWS 접근 권한을 위임해야 합니다. 이를 위해 신원 확인이 필요하고요. (위 IAM Roles Anywhere에서 신원 확인했던 것처럼) 이것 또한 Assume Role 방식으로 가능해야 합니다.

신원 확인

신원 확인을 위해 OIDC는 JWT 방식을 사용합니다.

1) AWS 계정 설정

우선 사용자는 자신의 AWS 계정에 OIDC Provider (ex. GitHub)를 등록해야 합니다.

사용자는 Role을 생성하고 Trust Policy의 Principal으로 Federated: OIDC Provider ARN을 등록합니다. 그리고 OIDC Provider가 AWS 리소스에 접근할 수 있도록 Permission Policy를 연결합니다.

2) 임시 자격 증명 발급

이제 OIDC Provider에게 요청하여 JWT (id_token)를 발급받습니다. (GitHub Actions 워크플로우 실행 시 발급)

위에서 얻은 JWT와 앞서 생성한 Role ARN을 가지고 AWS STS (Security Token Service)로 요청하여 임시 자격 증명을 획득합니다.

참고로 OIDC는 OAuth 2.0 레이어 위에 인증을 붙인 것입니다. (OAuth 2.0 기반임)

SAML 및 SCIM

앞서 OIDC가 JWT로 신원 확인했다면, SAML (Security Assertion Markup Language)은 XML로 신원 확인합니다.

SCIM (System for Cross-domain Identity Management)는 도메인 간 ID 관리 시스템으로, 자동으로 계정을 생성/삭제/수정 관리해줍니다. (자동 프로비저닝)

SAML은 주로 기업 SSO 환경에서 사용됩니다.

Okta 같은 Identity Provider가 SAML Assertion(XML)을 발급하고, 사용자는 이를 AWS에 제출하여 임시 자격 증명을 받습니다.

SAML이 오래된 방식이라 주로 새 프로젝트에서는 OIDC 방식을 사용한다고 합니다.

Roles Anywhere vs OIDC vs SAML

항목Roles AnywhereOIDCSAML
신원 확인 방식X.509 인증서JWTXML (SAML Assertion)
적합한 환경온프레미스, IoTCI/CD, SaaS기업 SSO
발급 주체CAIdentity Provider (GitHub, Google 등)Identity Provider (Okta 등)
AWS APIrolesanywhere:CreateSessionsts:AssumeRoleWithWebIdentitysts:AssumeRoleWithSAML
관리 복잡도높음 (인증서 갱신)낮음중간
주요 사용 사례데이터센터 서버, 임베디드GitHub Actions, Terraform CloudOkta -> AWS Console SSO

4. 프로젝트에 활용하려면?

외부 애플리케이션이 사용자의 AWS 리소스에 접근해야 한다면?

예를 들어 내가 신규 프로젝트를 구상 중인데, 서비스에서 고객의 AWS 계정에 있는 S3, EC2 등에 접근해야 하는 상황을 가정해 봅시다.

일단 장기 자격 증명으로 인증하는 방법은 피해야 합니다. 만료되지 않기에 노출 시 보안 위험이 있으며 키 로테이션 관리 부담이 있기 때문입니다.

임시 자격 증명으로 인증할 수 있는 방법으로 Roles Anywhere (인증서), OIDC (JWT), SAML (XML) 방법을 고려해볼 수 있습니다.

어떤 방법이 나을까요? 아니면 또 다른 방법이 있을까요?

잘못된 내용에 대한 지적이나 피드백 환영합니다!

AWS 공식 문서

profile
Invisible Treasure

0개의 댓글