# GitHub Actions에는 패키지 관리자가 있지만, 최악일 수 있다

> Clean Markdown view of GeekNews topic #24931. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=24931](https://news.hada.io/topic?id=24931)
- GeekNews Markdown: [https://news.hada.io/topic/24931.md](https://news.hada.io/topic/24931.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2025-12-09T09:44:40+09:00
- Updated: 2025-12-09T09:44:40+09:00
- Original source: [nesbitt.io](https://nesbitt.io/2025/12/06/github-actions-package-manager.html)
- Points: 2
- Comments: 2

## Topic Body

- GitHub Actions는 워크플로 파일의 `uses:` 구문을 통해 **패키지 의존성을 선언하고 실행하는 구조**를 가지며, 이는 사실상 패키지 관리자 역할을 수행  
- 그러나 **락파일(lockfile), 무결성 해시, 전이 의존성 고정, 의존성 트리 가시성** 등 다른 패키지 관리자들이 기본으로 제공하는 기능이 전혀 없음  
- 연구 결과, **대부분의 GitHub Actions 사용자가 검증되지 않은 외부 코드**를 실행하며, 코드 주입 취약점이 수천 개 워크플로에서 발견됨  
- GitHub이 일부 완화책(불변 릴리스, SHA 고정 정책 등)을 도입했지만, **전이 의존성이나 재현성 문제**는 여전히 해결되지 않음  
- 이러한 구조적 결함은 **소프트웨어 공급망 보안 전반에 영향을 미치며**, GitHub Actions를 기반으로 한 다른 CI 시스템에도 동일한 문제가 전파됨  

---

### GitHub Actions의 패키지 관리 구조와 문제점
- `uses: actions/checkout@v4` 같은 구문은 **의존성 선언**이며, GitHub이 이를 해석해 다운로드 및 실행함  
  - 이는 일반적인 패키지 관리 동작과 동일하지만, **락파일이 없어 실행마다 다른 버전이 선택될 수 있음**
- 다른 패키지 관리자(npm, Cargo, NuGet 등)와 비교했을 때, Actions는 **락파일, 전이 핀닝, 무결성 검증, 의존성 트리 가시성, 해석 명세** 모두 결여  
- **락파일 부재**가 핵심 문제로, 실행 시마다 의존성 해석이 달라져 **비결정적 빌드**가 발생  

### 보안 연구 결과와 취약성
- USENIX Security 2022 연구에 따르면, **99.7%의 리포지토리가 외부 개발자의 Actions를 실행**하고, **97%는 검증되지 않은 제작자**, **18%는 보안 업데이트 누락** 상태  
- 후속 연구에서는 **2.7백만 워크플로 중 4,300개 이상에서 코드 주입 취약점**이 발견됨  
- GitHub Actions는 **admittance control, execution control, code control, secrets 접근 제어** 등 CI/CD 필수 보안 속성을 충분히 제공하지 않음  

### 주요 기술적 결함
- **가변 버전 문제**: `@v4` 같은 태그는 유지자가 새 커밋으로 재태깅할 수 있어, 코드가 **조용히 변경**됨  
  - 락파일이 있다면 해당 태그가 어떤 SHA로 해석되었는지 기록 가능  
- **전이 의존성 불투명성**: Composite Action 내부에서 호출하는 다른 Action은 **보이지 않으며 제어 불가**  
  - 연구에 따르면 JavaScript Actions의 54%가 보안 약점을 포함하며, 대부분이 **간접 의존성**에서 발생  
  - `tj-actions/changed-files` 사건에서는 전이 의존성 업데이트를 통해 **비밀 유출 공격**이 발생  
- **무결성 검증 부재**: npm이나 Cargo는 해시를 기록해 다운로드 검증을 수행하지만, Actions는 **SHA 기반 신뢰에만 의존**  
- **재실행 비재현성**: GitHub 측이 “버전이 강제 푸시되면 최신 버전을 가져온다”고 명시, **같은 워크플로라도 다른 코드 실행 가능**  
- **의존성 트리 비가시성**: npm의 `npm ls`나 Cargo의 `cargo tree` 같은 기능이 없어, **전체 의존성 구조를 확인할 방법 없음**  
- **해석 규칙 비공개**: Actions의 의존성 해석은 문서화되지 않았으며, `ActionManager.cs` 코드에 단순한 재귀 다운로드 로직만 존재  

### 추가 구조적 한계
- **중앙 레지스트리 부재**: Actions는 Git 리포지토리에 존재하며, **보안 스캔·악성 탐지·타이포스쿼팅 방지** 기능이 없음  
- **공유 환경 문제**: 여러 Action이 동일한 `$PATH`를 수정해 **실행 순서에 따라 결과가 달라짐**  
- **오프라인 실행 불가**: GitHub에서 매번 다운로드해야 하며, **네트워크 없이 실행 불가능**  
- **네임스페이스 취약성**: GitHub 사용자명이 곧 네임스페이스로, **계정 탈취나 오타 공격**에 노출  
  - 락파일과 무결성 해시가 있다면 코드 변경 시 빌드 실패로 탐지 가능  

### 설계 배경과 파급 효과
- Actions 러너는 원래 **Azure DevOps 기반**으로, 내부 신뢰 환경을 전제로 설계됨  
  - GitHub이 이를 공용 마켓플레이스로 확장하면서 **신뢰 모델을 재설계하지 않음**  
- 이로 인해 **락파일, 무결성 검증, 전이 핀닝, 의존성 가시성** 같은 기본 기능이 누락  
- OIDC 기반 **패키지 자동 배포 기능**이 확산되면서, Actions의 보안 결함이 **패키지 레지스트리 전체 공급망 보안에 영향**  
- GitLab CI는 `integrity` 키워드를 도입해 해시 검증을 지원하지만, **GitHub은 동일 요청을 “계획 없음”으로 종료**  
- Forgejo Actions 등 **GitHub 호환 CI 시스템**도 동일한 구조를 유지해야 하므로, **결함이 생태계 전반으로 확산**  

### 개선 제안과 현황
- 커뮤니티는 **락파일 지원(issue #2195)** 을 요청했으나, GitHub은 2022년에 “계획 없음”으로 닫음  
- Palo Alto 연구는 **SHA 고정만으로는 전이 의존성 보호 불가**함을 입증  
- 일부 팀은 **Dependabot 업데이트, 자체 리포지토리 벤더링, zizmor 보안 스캐너** 등으로 보완  
- 근본적 해결책은 **모든 Action과 전이 의존성의 SHA 및 무결성 해시를 기록하는 락파일 도입**  
- GitHub이 이를 채택하지 않는 한, **CI/CD 공급망의 신뢰성 확보는 불가능**

## Comments



### Comment 47553

- Author: holywork
- Created: 2025-12-11T07:03:25+09:00
- Points: 1

털려봐야 정신 차리겠죠 뭐

### Comment 47430

- Author: neo
- Created: 2025-12-09T09:44:41+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=46189692) 
- GHA(GitHub Actions)를 옹호하고 싶진 않지만, 문서에는 안정성과 보안을 위해 **커밋 SHA 고정**을 권장한다고 명시되어 있음  
  직접 lock 파일처럼 구현할 수는 있지만, **transitive dependency**는 제어 불가능하므로 완전하지 않음  
  결국 보안 패치 추적과 해시 갱신의 부담이 생기며, 이런 이유로 해시 기반 고정이 널리 쓰이지 않는 듯함
  - GitHub은 Actions 출시 직후부터 이 문제를 알고 있었음에도, **버전 고정 기능**을 실질적으로 개선하지 않았음  
    대부분의 사용자는 문제를 인식하지 못하고, 인식한 사람도 SHA를 거의 사용하지 않음  
    나는 개인적으로 Actions를 좋아하고 몇 가지를 유지보수하지만, 공개 저장소를 보면 90%가 `@v1`, 9%가 `@v1.2`, 1%만 커밋 SHA를 씀  
    GitHub이 조금만 투자해도 **lock 파일 솔루션**을 만들 수 있었을 것임
  - 문서의 전략은 **transitive dependency** 문제를 해결하지 못하므로, 실제로는 근본적인 해결책이 아님
  - 커밋 SHA 고정이 안정적이라는 말은 현실적으로 틀림  
    종종 특정 Node 버전이나 API 버전에 의존하기 때문에, 오히려 **@main**을 쓰는 게 더 나았던 경험이 있음
  - SHA를 쓰는 건 오히려 **안티 패턴**이라고 생각함  
    “고정된 버전”을 얻는다고 착각하지만 실제로는 그렇지 않음  
    두 번이나 문제를 겪고 나서 깨달았음 — lock 파일이 있거나 없거나 둘 중 하나임

- GitHub이 자체 Actions를 거의 **유지보수하지 않고**, 기본 기능조차 **비공식 포크**에 의존하게 됨  
  생태계 전체가 임시방편으로 유지되는 느낌임
  - 이런 상황은 당분간 나아지지 않을 듯함  
    GitHub이 기능 개발보다 **Azure 마이그레이션**을 우선시한다고 발표했기 때문임  
    [관련 기사](https://thenewstack.io/github-will-prioritize-migrating-to-azure-over-feature-development/)
  - 흥미로운 점은 GitHub이 꽤 비싼 서비스라는 것임  
    우리 소규모 회사도 매달 200달러 이상을 지불함  
    Windows보다 GitHub 구독이 더 중요한 **신규 수익원**으로 여겨지는 듯함
  - **setup-* actions**의 품질이 눈에 띄게 떨어졌고, 이상한 결정이 많아짐  
    아마 원 저자들이 이미 회사를 떠난 듯함
  - 이런 얘기는 처음 들었는데, 혹시 구체적인 예시가 있는지 궁금함
  - 최근 GitHub이 **AI 개발에 집중하기 위해** 일반 기능 개발 속도를 늦춘다고 발표하지 않았는지?

- 혹시 **ArgoCD**를 CI 파이프라인으로 써본 사람이 있는지 궁금함

- GHA는 ‘**less is more**’ 철학의 실패 사례라고 생각함  
  업계 표준이 된 게 가장 큰 문제임  
  조금만 투자해도 훨씬 나은 CI를 만들 수 있었는데, MS가 **IE6 시절의 실수**를 반복한 느낌임  
  이제는 비교 경험이 없는 젊은 엔지니어 세대가 그 한계를 인식하지 못함
  - GHA가 정말 형편없다는 데 모두 동의하지만, **무료 컴퓨팅 리소스**가 제공된다는 점 때문에 다들 계속 씀  
    나는 은퇴한 노트북을 **Woodpecker** 서버로 돌려볼 생각임. 사람들이 싫어하지 않는 CI가 어떤지 궁금함
  - 예전에는 **VSS**를 써야 했던 세대라서, 지금의 GitHub조차 그때보단 훨씬 나은 환경이라고 느낌
  - 나는 대부분의 작업을 **로컬에서 직접 수행**하는 편임  
    GHA는 그에 비해 별다른 가치가 없는 것 같음

- 회사가 Jenkins/Ansible에서 GHA로 옮기려 했을 때 반대했는데, 지금 보니 잘한 선택 같음  
  CI는 항상 **유지보수 부담**이 크고, 특히 Mac 환경은 여전히 다루기 까다로움

- “GitHub이 올바른 SHA 코드를 제공한다고 믿는가?”라는 질문에,  
  대부분이 **GitHub 호스팅 러너**를 쓰는 현실을 보면, 그걸 믿지 못한다면 이미 더 큰 문제가 있는 셈임

- 만약 GitHub Actions가 **로컬 우선(local-first)** 구조로, **Nix 기반 잠금(locking)** 을 지원한다면 어떨까 하는 생각이 듦  
  [cachix/cloud.devenv.sh](https://github.com/cachix/cloud.devenv.sh)
  - 아이러니하게도 그 코드조차 **GitHub에 호스팅**되어 있음

- 많은 서드파티 Actions가 문서나 예제에서 **master 브랜치**를 직접 참조함  
  악의적인 푸시 한 번이면 수많은 저장소에서 **데이터 유출**이 가능함  
  태그를 써도 이동 가능하므로 완전한 방어는 아님

- 연구자들이 말한 CI/CD의 네 가지 핵심 보안 속성(인증, 실행, 코드, 비밀 접근)을 보며 의문이 생김  
  CI/CD가 정말 **비밀(secrets)** 에 접근할 필요가 있을까?  
  API 호출 권한만 있으면 충분하다고 생각함  
  이상적인 시스템은 비밀을 직접 다루지 않고, **보안 엔클레이브** 같은 어댑터를 통해 간접적으로 처리해야 함
  - “좋은 CI는 비밀을 지원하지 않아야 한다”는 말은 결국 **복잡한 비밀 관리 방식**을 제안하는 셈임  
    현실적으로 고객 대부분은 여전히 비밀을 필요로 함
  - 이론적으로는 맞지만, 실제로 사람들은 CI/CD에 비밀을 넣을 수밖에 없음  
    플랫폼이 최소한 **안전한 비밀 관리 메커니즘**을 제공해야 함  
    특히 오픈소스 프로젝트는 CI에서 직접 배포를 원하기 때문임
  - 우리 회사는 QNX 컴파일러나 Coverity 같은 **상용 도구**를 쓰는데, 이들은 라이선스 서버 접근을 위해 비밀이 필요함  
    “보안 엔클레이브 방식”이 구체적으로 어떻게 다른지 궁금함
  - CI/CD가 인프라와 완전히 통합되어 있다면 비밀 없이도 배포가 가능하겠지만,  
    현실적으로는 환경마다 다르고 구현 비용이 커서 대부분은 **컨테이너 + 환경변수** 방식으로 정착됨
  - 여러 클라우드 DB와 호환성을 테스트하려면 각 DB에 접근할 **자격 증명**이 필요함  
    이런 테스트를 자동화하려면 비밀이 불가피함

- **lock 파일**을 저장소에 커밋해야 한다면, 처음 생성 시점에 **부트스트래핑 문제**가 생김  
  이를 해결하려면 Actions를 **로컬에서 실행**할 수 있는 기능이 필요함  
  [nektos/act](https://github.com/nektos/act) 같은 도구가 있지만, 이는 주로 디버깅용임  
  아마도 **정적 분석 기반의 별도 메커니즘**이 필요할 것임
