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

2025년 5월 28일


기존에는 IAM 사용자를 생성하고 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY를 GitHub Secrets에 등록해 배포 시 인증에 사용했다.

문제:

  1. 보안 리스크: AWS 접근 키를 외부 서비스(GitHub)에 저장하는 구조.
  2. 키 로테이션: AWS 보안 권고(IAM Best Practices)에 따르면 90일마다 키를 교체해야 하며, 이를 매번 수동으로 관리해야 한다.

해결: **OIDC(OpenID Connect)**를 도입해 키 없이 IAM 역할 기반으로 인증한다.


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가 JWT를 검증한 후 1시간짜리 임시 토큰을 발급한다.


적용 과정

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

자격 증명 공급자(Identity Provider) 생성:

  • AWS IAM > 자격 증명 공급자 > GitHub(token.actions.githubusercontent.com)를 OIDC 공급자로 등록한다.

IAM 역할(Role) 생성:

  • GitHubDeployRole 이름으로 역할을 만들고 배포에 필요한 권한(ECR, SSM 등)을 연결한다.

신뢰 관계(Trust Relationship) 설정:

  • 특정 리포지토리에서만 역할을 수행할 수 있도록 조건(Condition)을 설정한다.
{
  "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단계 워크플로우 수정

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 }}
    aws-region: ${{ secrets.AWS_REGION }}

  • GitHub Secrets에서 AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY를 제거하고 역할 ARN 하나만 남긴다.
  • 90일 키 로테이션이 불필요해진다. 임시 토큰은 1시간 후 자동 만료된다.