Access key, Secret 방식의 문제점
Github actions workflow를 활용해서 테스트/배포 등을 관리하는 경우 필수적으로 클라우드 서비스(AWS, GCP, Azure같은) 접근권한이 필요하다.
이 때 일반적으로 클라우드 provider가 제공하는 패스워드나 토큰을 이용하는데 보통 github secret에 직접 값을 저장하고 workflow에서 저장된 값을 이용해 배포 커맨드를 실행하는 형태로 활용한다.
그런데 일단 배포에 필요한 권한 이상으로 설정된 IAM User의 credential을 저장소에 복사해서 담아놓는것의 찝찝함은 둘째치고 일단 값을 복사해서 저장소에 넣어놓는 과정 자체가 귀찮다. 거기다 credential 정보가 털리면 직접 revoke하기 전까진 매우 위험한 상황에 놓이게 된다.(Admin 권한이면 재앙)
OpenID Connect(OIDC)가 뭐임?
OpenID Connect란 OAuth 2.0 framework를 기반으로 만들어진 identity layer이다. Third party application이 사용자의 identity를 검증하고 프로필 정보를 얻는데 활용한다.
자세한건 여기
어쨌든 github에서 cloud provider에게 접근 권한을 요청하면 짧은 기간동안만 유효한 토큰을 발급해주고 해당 토큰을 이용해 배포에 필요한 자원에 접근하는 방식이다.
job이 끝난 이후엔 자동으로 토큰이 만료되기 때문에 access key를 직접 저장소에 보관하는 방식보다 훨씬 안전하다.
설정은 어떻게?
Provider 설정
AWS를 기준으로 여기에 자세히 잘 설명되어 있다.
먼저 Identity provider를 설정해주어야 한다.
- 우선 IAM - Identity providers 메뉴에서
Add provider
- provider URL, Audience에 각각
https://token.actions.githubusercontent.com
,sts.amazonaws.com
입력
다음으로 아래와 같이 Role을 설정해준다.
- IAM > Roles 메뉴에서
Create role
버튼 클릭 Trusted entity type
중Web identity
를 선택하고 아래의identity provider
,Audience
에 위에서 등록한 값을 선택하고Next
- 다음 단계에서 배포에 필요한 권한을 추가(s3, cloudfront 등)
이제 aws에서의 설정은 끝이났고 github action에 설정을 추가해주어야 한다.
Github Actions 설정
아래의 두가지 설정을 workflow yaml에 추가해주어야 한다.
- token에 대한 permission 추가
aws-actions/configure-aws-credentials
액션 관련 설정
대충 아래와 같은 형태로 yaml파일을 설정해주면 된다
# Sample workflow to access AWS resources when workflow is tied to branch# The workflow Creates static website using aws s3name: AWS example workflowon: pushenv: BUCKET_NAME : "<example-bucket-name>" AWS_REGION : "<example-aws-region>"# permission can be added at job level or workflow level permissions: id-token: write contents: read # This is required for actions/checkoutjobs: S3PackageUpload: runs-on: ubuntu-latest steps: - name: Git clone the repository uses: actions/checkout@v3 - name: configure aws credentials uses: aws-actions/configure-aws-credentials@v1 with: role-to-assume: arn:aws:iam::1234567890:role/example-role role-session-name: samplerolesession aws-region: ${{ env.AWS_REGION }} # Upload a file to AWS s3 - name: Copy index.html to s3 run: | aws s3 cp ./index.html s3://${{ env.BUCKET_NAME }}/
이제 저장소에 access key와 secret을 저장해두지 않고도 프로젝트를 자동으로 배포할 수 있게 되었다.