[AWS] GitHub Actions OIDC 도입으로 Access Key 없이 배포하기

AWS Access Key를 제거하고, OIDC(OpenID Connect)를 도입하여 키 관리 부담 없이 안전한 배포 파이프라인을 구축한 과정을 공유합니다.

2025년 5월 28일


기존에는 IAM에 사용자를 추가하고 정책에 권한을 추가하여 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY를 GitHub Secrets에 등록해서 사용했습니다. 깃헙 러너에서 배포 시 로그인하는 방법으로 사용했었는데, 운영하면서 몇 가지 보안적 찜찜함관리의 불편함을 느꼈습니다.

  1. 보안 리스크: 액세스 키는 AWS의 서비스에 접근이 가능한 사용자의 키인데 다른 서비스인 github에 올려둔다는건 찜찜함이 있음.
  2. 키 로테이션의 압박: AWS 보안 권장 사항(Security Hub, IAM Best Practices)에 따르면 90일마다 키를 교체해야 함. 권고사항에 따라 매번 시크릿을 교체해줘야하는 관리의 불편함이 있음.

그래서 방법을 찾던 중 OIDC(OpenID Connect)를 도입 하여 키 관리 부담 없이 배포 파이프라인을 구축하기로 했습니다.


OIDC (OpenID Connect)란?

*OpenID Connect (OIDC)**는 OAuth 2.0 프로토콜을 기반으로 한 사용자 신원 확인(Identity Authentication) 표준 프로토콜입니다.

  • AWS OIDC는 이 표준을 활용하여 다음과 같은 구조를 만듭니다.
  • Identity Provider (IdP): 신원을 보증하는 곳 (여기서는 GitHub).
  • Service Provider (SP): 서비스를 제공하는 곳 (여기서는 AWS).
  • Trust Relationship (신뢰 관계): AWS에게 "GitHub이 발행한 토큰(JWT)은 믿어도 된다"라고 설정하는 것.
  • 작동 원리: GitHub Actions가 배포를 시작할 때, AWS에게 요청하면 AWS가 검증 후 1시간짜리 임시 토큰(Role) 을 발급해줍니다.

적용 과정

크게 AWS 설정과 GitHub 설정 두 단계로 진행했습니다.

1단계: AWS 설정 (자격 증명 공급자 및 역할 생성)

  1. 자격 증명 공급자(Identity Provider) 생성:
    • AWS IAM > 자격 증명 공급자 메뉴 접속.
    • GitHub(token.actions.githubusercontent.com)를 OIDC 공급자로 등록합니다.
  2. IAM 역할(Role) 생성:
    • GitHubDeployRole(원하는 이름)이라는 역할을 만들고, 배포에 필요한 권한(ECR, SSM, S3 등)을 연결합니다. 이전 사용자에 연결했던 정책 그대로...
  3. 신뢰 관계(Trust Relationship) 설정:
    • 아무나 이 역할을 쓰면 안 되므로, 내 특정 리포지토리에서만 이 역할을 수행할 수 있도록 조건(Condition)을 걸어줍니다.
/* 신뢰 관계 정책 예시 (Trust Relationship) */
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "arn:aws:iam::[내AccountID]:oidc-provider/token.actions.githubusercontent.com"
      },
      "Action": "sts:AssumeRoleWithWebIdentity",
      "Condition": {
        "StringLike": {
          "token.actions.githubusercontent.com:sub": "repo:내GitHub아이디/내리포지토리이름:*"
        }
      }
    }
  ]
}

2단계: GitHub 설정 (Secrets 교체)

  1. 기존의 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 삭제하고
  2. 대신 AWS_ROLE_ARN이라는 이름으로 위에서 생성한 역할의 ARN 주소만 등록했습니다.

3단계: 워크플로우(YAML) 수정

deploy.yml 파일에서 인증 방식을 변경했습니다.

# [Before] 기존 방식 (Access Key)
# - uses: aws-actions/configure-aws-credentials@v2
#   with:
#     aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
#     aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}


# [After] 변경된 방식 (OIDC Role)
# 이 부분이 꼭 필요합니다!
permissions:
  id-token: write # AWS 인증(OIDC) 요청을 위해 필수
  contents: read # 코드 체크아웃을 위해 필수

- uses: aws-actions/configure-aws-credentials@v4
  with:
    role-to-assume: ${{ secrets.AWS_ROLE_ARN }} # 역할 ARN 사용
    aws-region: ${{ secrets.AWS_REGION }}

마무리

이제 SSM으로 서버 접속 보안을 챙기고, OIDC로 인증 보안까지 챙겼으니 훨씬 든든한 배포 환경이 되었습니다. 90일마다 키를 교체해줘야 하는 부담이 없어졌습니다.