GitHub Isn't Just a Remote Git Server: How Spoke Clusters, Fork Alternates, and Actions Runner Sandboxes Work Under the Hood
GitHub은 단순한 원격 Git 서버가 아닙니다: Spoke 클러스터, 포크 공유 객체, Actions 실행 환경의 작동 방식
GitHub의 대규모 저장소 운영을 Spokes 복제, fork의 Object Alternates, Pull Request용 참조, Actions 실행 환경과 OIDC 인증으로 설명합니다. 마지막에는 pull_request_target에서 외부 코드를 실행할 때 비밀 정보가 노출될 수 있는 설정 위험을 다룹니다.
- 주제
에디터 노트
가장 구체적인 보안 조언은 pull_request_target에서 외부 PR 코드를 체크아웃해 실행하지 말라는 부분입니다. 권한이 있는 워크플로와 신뢰할 수 없는 코드를 결합하는 위험을 예시 설정으로 보여주고, 메타데이터 처리와 코드 테스트를 분리하라고 제안합니다. 반면 Spokes의 복제 절차와 95% 이상 절감 수치, Actions 실행기의 내부 구성은 출처나 적용 조건을 제시하지 않은 채 단정합니다. OIDC도 장기 키를 없애지만, 발급된 임시 자격 증명은 유효 기간 동안 사용될 수 있으므로 '자격 증명이 유출될 수 없다'는 글의 표현은 앞서 설명한 15~60분 유효 기간과 맞지 않습니다. 아키텍처 설명은 이 글이 제시한 내용으로 읽되, 보안 조언의 근거와 OIDC의 잔여 위험은 구분해야 합니다.
AI 요약
GitHub의 웹 인터페이스 뒤에는 저장소 복제와 공유, Pull Request 계산, 자동화 작업 격리를 담당하는 여러 시스템이 있습니다. 이 글은 Spokes, Git의 Object Alternates와 숨겨진 참조, GitHub Actions의 실행 환경과 인증 방식을 차례로 설명합니다.
Spokes로 저장소 복제
일반 Git 서버는 저장소 파일을 한 서버에 두고 참조를 잠그며 갱신합니다. 글은 GitHub가 수백 페타바이트 규모의 Git 데이터를 관리하기 위해 Spokes라는 전용 저장소 서버 구조를 사용한다고 설명합니다. 저장소마다 Primary 한 대와 Replica 두 대를 둡니다. push가 들어오면 Primary가 packfile을 검증하고 두 복제본에 데이터를 전송합니다. 세 노드 중 둘이 디스크 기록과 SHA 검증을 마치면 참조를 갱신하고 성공 응답을 보냅니다. 서버나 디스크에 장애가 나면 복제본을 Primary로 승격하고 새 복제본을 마련한다고 서술합니다.
포크는 객체를 공유하고 PR은 참조로 표현합니다
Linux 저장소 크기를 약 4.5GB, 공개 포크 수를 5만 개 이상으로 잡으면 각 포크를 통째로 복사할 경우 약 225TB가 필요하다고 계산합니다. GitHub는 fork의 .git/objects/info/alternates 파일에 원본 저장소의 객체 경로를 적어 공통 이력을 공유한다는 설명입니다. 포크에 새로 생긴 커밋과 파일 객체는 별도 저장소에 기록합니다. 글은 이 방식으로 포크가 거의 즉시 만들어지고 오픈소스 저장 공간을 95% 이상 줄인다고 주장합니다.
Pull Request는 Git 자체 기능이 아니라 refs/pull/ 네임스페이스의 참조로 다룹니다. refs/pull/42/head는 제안된 변경의 커밋을 가리키고 refs/pull/42/merge는 기본 브랜치와의 병합 결과를 나타냅니다. 따라서 git fetch origin pull/42/head:pr-42 명령으로 PR 코드를 로컬 브랜치에 가져올 수 있습니다. 글에 따르면 PR이 갱신되거나 기본 브랜치가 바뀌면 백그라운드 작업이 3-way merge를 계산해 충돌 여부를 표시합니다.
Actions 실행과 클라우드 인증
워크플로 오케스트레이터는 YAML 설정을 읽어 작업 의존성을 DAG로 구성하고, 호스팅 실행기는 사전 준비된 Azure 가상 머신에서 작업을 실행한다고 설명합니다. 작업이 끝나면 VM을 폐기해 다음 실행에 디스크 상태나 메모리 내용이 남지 않도록 합니다. 클라우드 배포에는 장기 보관 키 대신 OIDC를 사용할 수 있습니다. GitHub가 저장소와 브랜치 등의 정보를 담은 JWT를 발급하면 AWS STS나 Google Cloud가 토큰을 검증하고, 역할 정책이 일치할 때 15~60분 동안 유효한 임시 자격 증명을 제공합니다.
pull_request와 pull_request_target
외부 기여자의 코드가 들어오는 pull_request 워크플로는 글의 설명에 따르면 포크 맥락에서 실행되며 기본 GITHUB_TOKEN은 읽기 전용이고 저장소 비밀 정보도 제공되지 않습니다. 반면 pull_request_target은 대상 저장소의 권한과 비밀 정보에 접근할 수 있습니다. 여기에 PR의 코드를 checkout한 뒤 실행하면 공격자가 수정한 코드가 비밀 정보가 있는 환경에서 동작할 수 있습니다. 외부 코드를 빌드하거나 테스트할 때 pull_request를 쓰고, pull_request_target은 코드 실행 없이 라벨 지정 같은 메타데이터 작업에 한정하라고 권합니다.
원문: dev.to / 번역·요약: Trawling