업데이트됨

GitHub Actions에서 시크릿 공유하기 — Vault 없이도 OK

작성자

Vaulted의 GitHub Action을 사용하면 HashiCorp Vault 없이도 GitHub Actions에서 시크릿을 공유할 수 있어. 인프라 없이 암호화된 자기파괴 링크를 만들어주는 액션이야. 클라이언트 사이드 AES-256-GCM 암호화를 사용하며, 단일 워크플로 스텝으로 동작해 — Secrets Manager 서버나 클라우드 설정이 전혀 필요 없어.

CI 파이프라인에서는 임시 자격증명이 항상 필요해. 단 한 번의 실행에만 존재해야 하는 배포 키, 마이그레이션 중에 두 저장소 간에 전달되는 토큰, 한 워크플로에서 교체하고 다른 워크플로에서 사용하는 자격증명.

"시크릿 매니저를 써라"는 게 표준 조언이야. 하지만 워크플로 간에 자격증명 하나를 넘기려고 HashiCorp Vault를 구축하거나 AWS Secrets Manager를 설정하는 건, 편지 한 통 부치려고 창고를 임대하는 것과 다름없어.

GitHub 저장소 시크릿은 정적인 경우에 잘 맞아 — 수명이 긴 API 키, 배포 토큰, 서비스 계정 자격증명. 하지만 임시적이거나 동적인 상황에는 부족해.

문제: CI/CD에서의 임시 시크릿 공유

저장소 시크릿은 변경 빈도가 낮고 단일 저장소에서 소비하는 값을 위해 설계됐어. 다음 시나리오는 커버하지 못해:

  • 키 교체 중 일회성 인계 — 한 워크플로에서 자격증명을 교체하고, 다른 워크플로(또는 팀)가 새 값을 정확히 한 번만 가져가야 하는 경우.
  • 저장소 간 자격증명 공유 — 두 저장소가 수명이 짧은 토큰을 교환해야 하는데, 어느 쪽도 영구 저장하면 안 되는 경우.
  • 시간 제한 외부 인력 접근 — 계약자의 배포 기간이 끝나면 만료되어야 하는 CI 토큰.
  • 시크릿이 언제 소비됐는지 파악 — 저장소 시크릿은 값이 읽혔는지, 언제 읽혔는지에 대한 가시성을 전혀 제공하지 않아.

이건 임시 문제야 — 임시 해결책이 필요해.

가벼운 접근법: 암호화된 자기파괴 링크

Vaulted GitHub Action을 사용하면 워크플로에서 직접 암호화된 자기파괴 시크릿을 만들고 가져올 수 있어 — 관리할 인프라가 없어.

시크릿 만들기:

- name: Share rotated credential
  id: share
  uses: vaulted-fyi/share-secret@v1
  with:
    secret: ${{ steps.rotate.outputs.new_token }}
    views: 1
    expires: 1h

이 스텝은 암호화된 시크릿을 담은 URL을 출력해. 암호화 키는 URL 프래그먼트 안에 있기 때문에 Vaulted 서버에 전달되지 않아.

시크릿 가져오기:

- name: Get shared credential
  id: get
  uses: vaulted-fyi/share-secret/get@v1
  with:
    url: ${{ needs.rotate.outputs.secret_url }}

- name: Deploy with rotated credential
  run: ./deploy.sh
  env:
    API_TOKEN: ${{ steps.get.outputs.secret }}

가져오고 나면 링크는 소비되고 서버 측 암호문은 삭제돼. 시크릿은 해당 잡이 실행되는 동안에만 러너의 메모리에 존재해.

보안 모델

CI/CD 환경에서 안전하게 사용할 수 있는 세 가지 특성이 있어:

  1. Zero-knowledge 암호화. 시크릿은 GitHub 러너 내부에서 AES-256-GCM으로 암호화된 후에야 프로세스를 떠나. 암호화 키는 URL 프래그먼트에 포함되어 있으며, 서버로 전송되지 않아. Vaulted는 자신이 복호화할 수 없는 암호문만 저장해. 이게 CI/CD에 적용된 클라이언트 사이드 암호화야.

  2. 자동 로그 마스킹. 이 액션은 core.setOutput 전에 core.setSecret을 호출해서, 시크릿 값의 모든 줄을 GitHub의 로그 마스커에 등록해. 여러 줄로 된 시크릿은 줄 단위로 마스킹되어, 부분 일치도 워크플로 로그에서 가려져.

  3. 자기파괴 링크. 조회 제한과 시간 기반 만료는 서버 측에서 적용돼. views: 1expires: 1h로 만든 시크릿은 첫 번째 조회 또는 한 시간 후 — 둘 중 먼저 오는 시점에 — 영구 삭제돼.

시크릿 매니저 vs. 이 액션, 언제 뭘 써야 할까

시나리오시크릿 매니저Vaulted Action
수명이 긴 프로덕션 자격증명적합부적합
앱 런타임 설정 (DB URL, API 키)적합부적합
워크플로 간 일회성 자격증명 인계과도함적합
임시 저장소 간 토큰 공유과도함적합
외부 인력 CI 접근 시간 제한과도함적합
교체 후 자격증명 배포과도함적합

시크릿 매니저는 애플리케이션이 런타임에 소비하는 시크릿에 적합한 도구야. Vaulted는 인계를 위한 것 — 자격증명이 한 곳에서 다른 곳으로 이동하며 유지되어서는 안 되는 그 순간을 위해서야.

시작하기

어떤 워크플로에든 이 액션을 추가하면 돼:

- uses: vaulted-fyi/share-secret@v1
  with:
    secret: ${{ secrets.TEMP_CREDENTIAL }}
    views: 1
    expires: 1h

GitHub Marketplace에서 찾을 수 있어. 이 액션으로 만든 시크릿은 웹 앱CLI와 호환돼 — 어느 쪽에서 만들어도 다른 쪽에서 가져올 수 있어.


Vault 서버 없이. IAM 정책 없이. 인프라 없이. 자기파괴하는 암호화 링크만 있으면 돼.


관련 글