← 전체 글로 돌아가기

CI/CD

GitHub Actions에서 환경변수를 로그에 출력하지 않기

Actions의 로그에 실수로 민감한 정보를 출력하는 것을 방지하는 방법들.

로그에 노출되는 정보의 위험

GitHub Actions는 각 step의 출력을 모두 로그에 남긴다. 만약 실수로 API 키나 토큰을 출력하면 공개 저장소라면 누구나 볼 수 있다.

- name: Deploy
  run: echo "Token: ${{ secrets.DB_PASSWORD }}"
  # 이렇게 하면 안 된다!

GitHub의 자동 마스킹

다행히 GitHub Actions는 secrets로 정의한 값들을 자동으로 마스킹한다.

- name: Show secret
  run: echo "My secret is ${{ secrets.SECRET_KEY }}"
  # 로그: My secret is ***

하지만 이건 완벽하지 않다. 값을 일부 변형하면 마스킹을 피할 수 있다.

run: echo "Key: $(echo ${{ secrets.API_KEY }} | tr -d ' ')"

변형된 값은 마스킹되지 않을 수도 있다.

좋은 방법들

1. 직접 출력하지 않기

- name: Deploy
  run: npm run deploy
  env:
    API_KEY: ${{ secrets.API_KEY }}
  # 환경변수로 전달만 하고 출력하지 않음

2. 로그 마스킹 명시

- name: Set up secrets
  run: |
    echo "::add-mask::${{ secrets.API_KEY }}"
    # 이제 이 값을 사용해도 로그에서 마스킹됨

3. 디버그 로그 비활성화

민감한 step에서는:

- name: Deploy
  run: npm run deploy
  env:
    ACTIONS_STEP_DEBUG: 'false'

4. 파일로 저장하기

- name: Write config
  run: |
    echo "${{ secrets.CONFIG_JSON }}" > config.json
    chmod 600 config.json
  # 파일에 저장되지 않고 실행할 때만 메모리에 로드

내 실수

처음에는 디버깅 목적으로 모든 환경변수를 출력했다가, 공개 저장소에서 엑세스 토큰이 노출되는 뻘짓을 했다. 그 이후로는 절대 secrets를 직접 echo 하지 않는다.

추가 팁

공개 저장소라면 더 조심해야 한다:

- name: Check token
  if: github.event_name == 'push' && github.ref == 'refs/heads/main'
  run: # 배포 step만 민감한 정보 사용

프라이빗 저장소라도 같은 원칙을 지키는 게 습관이다.