소개
이전 실습에서는 로봇 도우미가 창고에 자동으로 로그인했습니다. 그런데 비밀번호는 어디에서 가져왔을까요?
실제 자동화에서는 워크플로가 API 키, 비밀번호, 토큰과 같은 민감한 데이터를 사용해야 하는 경우가 많습니다. 이러한 값을 저장소 파일에 하드코딩해서는 안 됩니다.
GitHub 는 워크플로에서 사용하는 민감한 값을 보호된 방식으로 저장할 수 있도록 Secrets를 제공합니다. 파이프라인에는 권한이 부여된 액세스가 필요한 경우가 많으므로, 이는 CI/CD 보안의 핵심 관행입니다.
이는 자동화 보안에서 가장 중요한 경계 중 하나입니다. 파이프라인에는 자격 증명이 필요하지만, 자격 증명은 버전 관리에 커밋하지 않고 보호된 저장소에서 실행 시점에 주입해야 합니다.
이 실습에서는 다음을 수행합니다.
- 보관소에 시크릿 비밀번호를 만듭니다.
- 로봇이 비밀번호를 가져오도록 설정합니다.
- 로봇이 비밀번호를 출력하려고 해도 GitHub 가 비밀번호를 검열한다는 것을 확인합니다.
사전 요구 사항
계속해서 github-actions-basics 저장소를 사용합니다.
시크릿 만들기
애플리케이션이 데이터베이스에 연결해야 한다고 가정해 보겠습니다. 데이터베이스 비밀번호를 안전하게 저장해야 합니다.
DB_PASSWORD라는 이름의 시크릿을 만듭니다.
- GitHub 에서
github-actions-basics저장소를 엽니다. - Settings 탭을 클릭합니다.
- 왼쪽 사이드바에서 Secrets and variables 메뉴 항목을 찾아 클릭해 펼칩니다.
- Actions를 선택합니다.
- New repository secret이라고 표시된 녹색 버튼을 클릭합니다.

간단한 입력 양식이 표시됩니다.
- Name:
DB_PASSWORD를 입력합니다. (시크릿 이름에는 대문자를 사용하는 것이 일반적입니다.) - Secret:
SuperSafePassword123!을 입력합니다.
Add secret을 클릭합니다.
이제 DB_PASSWORD가 목록에 표시됩니다. 하지만 이제 값은 볼 수 없습니다. 시크릿을 저장하면 영구적으로 잠깁니다. 시크릿을 업데이트하거나 삭제할 수는 있지만, 저장한 값은 본인이나 다른 누구도 다시 확인할 수 없습니다.
시크릿 사용하기
이제 비밀번호를 안전한 보관소에 저장했으므로, 이 비밀번호를 사용하는 워크플로를 작성합니다.
여기서 중요한 패턴은 간접 참조입니다. 워크플로는 이름으로 시크릿을 참조하고, GitHub 는 실행 중에 값을 안전하게 확인합니다.
워크플로 파일에서는 ${{ secrets.YOUR_SECRET_NAME }} 구문을 사용해 모든 시크릿에 액세스할 수 있습니다.
프로젝트 디렉터리로 이동합니다.
cd ~/project
git clone https://github.com/your-username/github-actions-basics.git
cd github-actions-basics
참고: your-username을 실제 GitHub 사용자 이름으로 바꿉니다.
.github/workflows 폴더 안에 security-test.yml이라는 새 워크플로 파일을 만듭니다.
touch .github/workflows/security-test.yml
nano로 파일을 엽니다.
nano .github/workflows/security-test.yml
다음 내용을 추가합니다.
name: Security Test
on: [push]
jobs:
test-secret:
runs-on: ubuntu-latest
steps:
- name: Try to print secret
env:
MY_PASSWORD: ${{ secrets.DB_PASSWORD }}
run: echo "The password is $MY_PASSWORD"
여기서는 흥미로운 작업을 수행합니다. GitHub 보관소의 시크릿을 MY_PASSWORD라는 환경 변수로 옮긴 다음, echo를 사용해 출력하려고 합니다.
잠깐! 비밀번호를 로그에 출력하는 것은 매우 위험하지 않나요? 맞습니다. 매우 위험합니다! 하지만 여기서는 GitHub Actions 의 강력한 보안 기능을 보여 주기 위해 이렇게 합니다.
nano에서 저장하고 종료합니다.
마스킹 확인하기
이제 이 워크플로를 실행하고 시크릿을 유출하려고 하면 어떻게 되는지 확인합니다.
변경 사항을 커밋하고 푸시합니다.
git add .
git commit -m "Test secret masking"
git push
GitHub 에서 저장소의 Actions로 이동합니다.
"Security Test"워크플로 실행을 클릭합니다.test-secret작업을 클릭합니다."Try to print secret"단계를 펼칩니다.
출력을 확인합니다. 다음과 비슷한 내용이 표시되어야 합니다.
The password is ***

GitHub Actions 는 $MY_PASSWORD의 값이 시크릿에서 가져온 값임을 자동으로 인식합니다. 로그에 출력하기 전에 민감한 값을 검색하고 ***로 바꿉니다.
마스킹은 로그에 실수로 민감한 정보가 노출되는 피해를 줄여 주지만, 애초에 시크릿을 출력하지 않는 것이 더 나은 방법입니다. 보안 기능은 안전망이지, 부주의한 처리를 정당화하는 수단이 아닙니다.
이 "Masking" 기능이 사용자를 보호합니다. 실수로 시크릿을 출력하려고 하거나 사용 중인 도구가 지나치게 많은 정보를 출력하더라도, GitHub 가 이를 감지해 로그에서 민감한 데이터를 제거합니다.
GITHUB_TOKEN 참고: 이전 실습에서 사용한 ${{ secrets.GITHUB_TOKEN }}을 기억하시나요? 이 토큰도 정확히 같은 방식으로 작동합니다. GitHub 가 모든 실행마다 자동으로 만드는 시크릿이며, 그 값 역시 로그에서 마스킹됩니다.
요약
이 실습에서는 자동화 보안의 기본 사항을 배웠습니다.
- 보관소: GitHub Secrets 를 사용해 비밀번호와 같은 민감한 데이터를 저장했습니다.
- 액세스:
${{ secrets.NAME }}을 사용해 로봇이 해당 데이터에 액세스할 수 있도록 설정했습니다. - 마스킹: 실수로 정보가 유출되는 것을 방지하기 위해 GitHub 가 로그의 시크릿을 자동으로 삭제 (
***) 하는지 확인했습니다.
이제 안전한 자동화 파이프라인을 갖추었습니다. 마지막 실습에서는 DevOps 의 궁극적인 목표인 Continuous Deployment를 다룹니다. 로봇이 코드를 실제 운영 서버에 배포하도록 만드는 방법을 배웁니다!



