GitHub Actions 시크릿 관리: 워크플로에서 API 키와 비밀번호 보호하기
By Mirko Peters ·
GitHub Actions 시크릿을 올바르게 사용해 CI/CD 파이프라인을 보호하는 방법을 알아봅니다. API 키와 액세스 토큰을 안전하게 관리하는 모범 사례를 소개합니다.
Automatically translated with AI from the original post. Read the English original

자동화가 클라우드에서 사람의 개입 없이 완전히 실행될 때는 자격 증명을 안전하게 관리하는 것이 매우 중요합니다. GitHub Actions 시크릿을 효과적으로 관리하면 API 키, 배포 비밀번호, 액세스 토큰을 소스 코드 밖에 두면서도, 프로젝트를 빌드하고 배포하는 데 필요한 워크플로에서는 쉽게 사용할 수 있습니다.
핵심 요약
- 민감한 비밀번호, API 키, 액세스 토큰을 워크플로 YAML 파일에 직접 하드코딩하지 마십시오.
- GitHub는 저장소 시크릿, 조직 시크릿, 환경 시크릿이라는 세 가지 수준의 시크릿을 제공합니다.
- 시크릿은 GitHub에 도달하기 전에 이미 암호화되며, 실행 로그에서는 자동으로 마스킹됩니다.
- 환경 시크릿은 배포 자격 증명을 작업이 사용할 수 있게 되기 전에 사람의 승인 단계를 거치도록 강제할 수 있습니다.
- 항상 최소 권한 원칙을 따르고, 각 시크릿에 필요한 최소한의 권한만 부여하십시오.
일반 텍스트 자격 증명이 CI/CD에서 실패하는 이유
새 파이프라인을 서둘러 구성하는 개발자는 API 키를 워크플로 구성 파일에 그대로 붙여 넣고 싶은 유혹을 느끼기 쉽습니다. 워크플로가 비공개라면 누가 보겠느냐는 생각입니다. 하지만 이런 생각은 심각한 보안 취약점으로 이어집니다. 워크플로 파일은 버전 관리되므로, 모든 이전 리비전, 커밋, 브랜치에 YAML 문서에 작성된 내용이 영구적으로 기록됩니다.
또한 저장소의 권한은 자주 바뀌고, 비공개에서 공개로 전환되거나 기여자에 의해 포크되기도 합니다. 자격 증명이 구성 파일에 일반 텍스트 문자열로 존재한다면, 권한 설정 실수 하나만으로도 전체 프로덕션 환경이 노출될 수 있습니다. 구성 파일은 순수한 실행 지침으로만 다루고, 민감한 데이터는 암호화된 별도의 보관소에 저장하는 것이 현대 클라우드 보안의 기본 원칙입니다.
GitHub 시크릿의 세 가지 계층
GitHub는 자격 증명마다 적용 범위가 다르다는 점을 인지하고 있습니다. 개발자가 액세스 제어를 효율적으로 관리할 수 있도록, 이 플랫폼에서는 세 가지 조직 수준에서 시크릿을 구성할 수 있습니다.
저장소 수준 시크릿
저장소 시크릿은 단 하나의 프로젝트에만 속합니다. 독립형 애플리케이션을 개발하거나 단일 플러그인을 관리하는 경우, 저장소 시크릿은 연결 문자열과 배포 토큰을 해당 작업 공간에만 묶어 둡니다. 조직 내 다른 프로젝트에서는 이 시크릿에 접근할 수 없습니다.
조직 수준 시크릿
회사 내 여러 저장소가 중앙 컨테이너 레지스트리나 엔터프라이즈 코드 서명 인증서처럼 동일한 공유 리소스에 접근해야 할 때, 조직 시크릿을 사용하면 같은 항목을 중복으로 등록하지 않아도 됩니다. 관리자는 정책을 정의하고, 이 조직 전체 자격 증명을 상속받을 수 있는 특정 저장소나 팀을 지정할 수 있습니다.
환경 수준 시크릿
환경 시크릿은 스테이징이나 프로덕션 환경처럼 특정 배포 대상에 자격 증명을 연결합니다. 실제 시스템에 접근하는 데 필요한 키를 저장하는 곳이 바로 여기입니다. 특히 환경 시크릿에서는 필수 검토자를 설정할 수 있어, 프로덕션 자격 증명이 열려 러너에 전달되기 전에 사람이 배포 실행을 직접 승인하도록 보장할 수 있습니다.
GitHub가 전송 중인 데이터를 보호하는 방법
보안은 비밀 값을 어디에 저장하느냐에만 그치지 않고, 실행 과정에서 그 값이 어떻게 전달되는지까지 포함합니다. 비밀 값은 GitHub로 전송되기 전에 로컬 머신에서 암호화되므로, 네트워크를 통해 평문으로 전송되는 일이 없습니다. 일단 저장되면 리포지토리 설정 인터페이스에서도 완전히 숨겨져 표시되지 않습니다.
워크플로가 실행될 때는 ${{ secrets.DATABASE_URL } }와 같은 식 구문을 사용해 비밀 값을 이름으로 명시적으로 단계나 작업에 전달해야 합니다. 즉, 실수로 끼어들었거나 악의적인 서드파티 마켓플레이스 작업이라도 리포지토리의 모든 자격 증명을 자동으로 가져갈 수는 없으며, 사용자가 명시적으로 넘겨준 값만 받게 됩니다.
또한 GitHub는 작업 출력 로그를 자동으로 검사해 민감한 문자열을 가립니다. 스크립트가 실수로 비밀 값을 콘솔에 출력하면 GitHub가 해당 문자를 별표로 바꾸려고 시도합니다. 하지만 스크립트가 출력 전에 문자열을 조작하거나 인코딩할 수 있으므로, 로그 가리기에만 의존하는 것은 안전한 코드를 작성하는 일을 대신할 수 없습니다.
안전한 자동화를 위한 모범 사례
견고한 GitHub Actions 비밀 값 관리를 실천하려면 일상적인 습관을 갖춰야 합니다. 먼저, 구성 설정과 비밀 값을 항상 구분하십시오. 값이 공개 웹 사이트 주소, 환경 이름, 민감하지 않은 기능 플래그처럼 단순한 정보라면 팀원들이 파이프라인 동작을 쉽게 이해할 수 있도록 YAML 파일에 평문으로 두십시오. 비밀 값 기능은 반드시 기밀로 유지해야 하는 데이터에만 사용하십시오.
둘째, 최소 권한 원칙을 적용하십시오. 가능한 한 만료 기간이 짧고 권한 범위가 가장 좁은 세분화된 액세스 토큰을 생성하십시오. 배포 토큰이 특정 S3 버킷 하나에만 쓰기 작업을 하면 된다면, 전체 클라우드 인프라에 대한 관리자 권한을 주어서는 안 됩니다.
결론
GitHub Actions 비밀 값 관리를 제대로 익히면 CI/CD 파이프라인을 잠재적인 보안 위험 요소에서 견고한 엔터프라이즈급 자동화 엔진으로 바꿀 수 있습니다. 자격 증명을 코드와 분리하고 다단계 액세스 제어를 활용하면, 보안을 희생하지 않고도 소프트웨어를 빠르게 배포할 수 있습니다.
자동화 워크플로의 기본 원리를 더 알아보려면 전체 에피소드 듣기를 확인하십시오. 트리거, 작업, 러너를 설정하는 방법을 더 자세히 알고 싶다면 전체 토론을 들어 보십시오.
자주 묻는 질문
포크에서 온 풀 요청 안에서 GitHub Actions 비밀 값을 읽을 수 있습니까?
기본적으로 GitHub는 악성 코드가 실행되어 자격 증명을 탈취하는 것을 막기 위해, 외부 기여자(포크)의 풀 요청이 리포지토리 비밀 값에 접근하지 못하도록 합니다.
워크플로에서 특정 단계로 비밀 값을 전달하려면 어떻게 합니까?
단계나 작업 안의 'env' 컨텍스트를 사용해 GitHub 비밀 값을 환경 변수에 매핑하면 워크플로에 비밀 값을 전달할 수 있습니다. 예를 들면 env: API_KEY: ${{ secrets.MY_API_KEY } }와 같습니다.
GitHub Actions 비밀 값은 로그에서 반드시 숨겨집니까?
GitHub는 실행 로그에서 알려진 비밀 값을 자동으로 가리지만, 이것이 절대적인 보장은 아닙니다. 비밀 값이 출력되기 전에 조작, 인코딩 또는 변환되면 일부가 노출될 수 있습니다.
리포지토리 비밀 값과 환경 비밀 값의 차이는 무엇입니까?
리포지토리 비밀 값은 해당 리포지토리의 모든 워크플로에서 사용할 수 있는 반면, 환경 비밀 값은 스테이징이나 프로덕션 같은 특정 배포 환경에 연결되며 수동 검토 승인을 요구할 수 있습니다.