pile·
보안·인포그랩인포그랩·

GitLab Secrets Manager로 CI/CD 시크릿 유출 막기

GitLab CI/CD 변수에 시크릿을 넣고 Mask variable을 체크해 두면 안전해 보이지만, 마스킹은 등록된 원본 값과 정확히 일치하는 문자열만 가린다는 데서 출발한다. 시크릿을 base64로 인코딩해 출력하면 다른 문자열이 되어 그대로 로그에 찍히고, 디코딩하면 원래 값이 드러난다. GitLab 19.0에서 퍼블릭 베타로 전환된 OpenBao 기반 Secrets Manager를 중심으로 유출 지점과 구조적 원인, 대안 비교를 정리했다.

핵심 포인트
  • CI/CD 변수는 기본적으로 모든 job에 사용 가능해, 요청하지 않은 job에도 시크릿이 주어진다.
  • 전용 Vault를 붙이면 시크릿을 CI 설정 밖으로 빼주지만 인증할 시스템 하나, 유지할 접근 모델 하나, 감사 스트림 하나가 늘어나는 상시 운영 비용이 따른다.
  • CI 시스템의 변수 기능은 설정값을 편하게 주입하려고 만든 것이라 시크릿을 특정 job으로 한정한다는 개념이 설계에 없다. 환경 스코프가 있지만 그건 환경 단위이지 job 단위가 아니다.
  • 안전한 기본 경로가 없으니 사용자가 편의를 택하는 것은 부주의가 아니라 도구가 그렇게 유도한 결과다.
  • 발급은 클릭 한 번이면 끝나지만 회전·폐기·오프보딩을 의무화하거나 자동화하는 장치는 없어, 이 비대칭이 고아 크리덴셜을 만든다.
상세 정리
  • 유출 지점 1 소스 코드: API 키를 하드코딩하거나 설정 파일을 코드와 함께 커밋하는 데서 시작된다. 한 번 저장소 이력에 들어가면 파일을 지워도 커밋 기록에 남아 과거 이력에서 값을 되살릴 수 있다.
  • 유출 지점 2 CI 변수: 값이 프로젝트나 그룹 설정에 저장되고, 보호 변수로 지정하지 않는 한 보호 브랜치 외 파이프라인에도 그대로 제공된다. 설정 접근 권한이 있는 사용자가 열람하거나 덮어쓸 수 있고 파이프라인 접근 권한이 있는 누구나 읽을 수 있다.
  • 유출 지점 3 Job 로그: GitLab이 18.3에서 변수 기본값을 Masked로 바꿨지만, 스크립트가 값을 base64로 인코딩하거나 다르게 변형하면 변형된 형태는 가려지지 않는다.
  • 유출 지점 4 방치: CI 변수는 프로젝트 설정에 무기한 읽을 수 있는 상태로 남고, 자동 회전이나 폐기 절차가 없으면 퇴사자나 폐기된 통합의 크리덴셜이 그대로 살아남는다. 누구의 것인지조차 불분명한 고아 크리덴셜은 공격자에게 잊힌 출입문이 된다.
  • 구조적 원인 1 양적 증가: 마이크로서비스가 서로 통신하고 파이프라인이 돌고 외부 통합이 추가될 때마다 새 크리덴셜이 필요하다. 인증할 대상이 늘면 크리덴셜도 비례해 늘어 사람이 일일이 추적하기 어려워진다.
  • 구조적 원인 2 자리의 부재: 시크릿을 위한 전용 보관소가 기본으로 주어지지 않는다.
  • 구조적 원인 3 회수 장치의 부재: 정리할 동력이 생기지 않아 한번 만든 크리덴셜은 누군가 의식적으로 지우지 않는 한 그대로 남는다.
  • 저자는 이 문제를 개인의 책임으로만 돌리면 핵심을 놓친다고 짚는다. 개발 방식이 자동화되면서 시크릿을 많이 만들고 널리 노출하며 오래 방치하도록 구조화되고 있고, 빠른 배포가 우선시되면서 그 구조가 바로잡히지 않는다는 것이다.
  • Secrets Manager 소개: OpenBao 기반이며 GitLab 19.0(2026년 5월)에 퍼블릭 베타로 전환돼 GA를 앞두고 있어, 지금이 활용을 검토하기 좋은 시점이라고 본다.
  • 글의 구성으로 문제 해결 방식, 유사 도구 비교, 활용법, 유의 사항을 예고한다.
왜 읽나CI 변수 마스킹에 기대어 시크릿을 관리해 온 팀에게, 마스킹이 막지 못하는 지점과 전용 Vault 도입의 운영 비용, 그리고 GitLab 내장 대안의 위치를 정리해 준다.
인포그랩
인포그랩 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 보안·gitlab-engGitLab Blog·

    Serena MCP 에이전트의 치명적 원격 코드 실행 취약점 분석

    GitLab 보안팀이 AI 코딩 에이전트 Serena(월 PyPI 다운로드 13.6만 건)에서 치명적 원격 코드 실행 취약점을 발견했다. Jinja2 비샌드박스 환경과 신뢰 모델의 미검사 경로가 결합해 개발자가 악의적 저장소를 열기만 해도 코드가 실행된다. serena-agent 1.7.0에서 SandboxedEnvironment 교체로 수정 완료됐다.

    요약 이어보기
    #mcp#security#rce+2