본문 바로가기
프로그램 (PHP,Python)

공급망 위협을 차단하는 gVisor 기반 GitHub Actions 샌드박스 전략

by 날으는물고기 2025. 11. 3.

공급망 위협을 차단하는 gVisor 기반 GitHub Actions 샌드박스 전략

728x90

왜 샌드박스가 필요한가

  • 문제: GitHub Actions는 기본적으로 같은 VM 안에서 여러 step이 실행됩니다. 한 단계에서 악성 코드가 실행되면 다음 단계나 캐시, 러너 환경까지 영향을 줄 수 있습니다. 또한 캐시 토큰 오용(포이즈닝)과 체크아웃 토큰 노출 등 공급망(Supply Chain) 리스크가 현실적인 위협입니다.
  • 해결: 각 명령을 gVisor 샌드박스 안에서 실행합니다.
    • 루트 파일시스템: Ubuntu 24.04 유사 환경.
    • 툴 디렉터리(RUNNER_TOOL_CACHE): 읽기 전용 마운트.
    • 워크스페이스(GITHUB_WORKSPACE): 오버레이(기본 비영속, 변경사항이 호스트에 자동 반영되지 않음).
  • 효과: 단계 간 격리 강화, 캐시/토큰 남용에 따른 피해 확산 억제, 외부 PR/오픈소스 의존성 검증 시 안전성 향상.

위협 모델과 보안 목표

  • 위협 시나리오
    1. 외부 PR 코드가 악의적 스크립트를 수행해 이후 단계 환경을 오염.
    2. 캐시 키를 악용해 악성 바이너리나 스크립트를 주입.
    3. 체크아웃으로 내려온 토큰·자격증명이 워크스페이스에 남아 유출.
  • 보안 목표
    • 단계별 실행 환경을 경량 격리(샌드박스).
    • 워크스페이스 변경의 의도적 영속화만 허용(기본 비영속).
    • 자격증명 최소화네트워크 통제로 공급망 공격면 축소.
    • 캐시/아티팩트의 신뢰 경계 분리.

필수 운영 원칙

  1. 체크아웃 토큰 남김 금지
    • actions/checkout은 항상 persist-credentials: false.
    • 워크스페이스에 자격증명을 남기지 않는 것이 샌드박스 효과를 유지하는 핵심입니다.
  2. 워크스페이스 비영속 유지
    • persist-workspace-changes: false(기본): 샌드박스 내 변경사항이 호스트로 반영되지 않음.
    • 부득이하게 영속화가 필요하면, 해당 단계 이후는 신뢰 불가 구간으로 취급하고 잡(Job) 분리 또는 재체크아웃으로 경계 재수립.
  3. 네트워크 최소화
    • 재현성/락파일 무결성 검증 단계는 disable-network: true로 외부 다운로드를 차단.
    • 네트워크가 필요한 설치·빌드는 별도 단계/잡에서 수행.
  4. 권한 최소화
    • 워크플로 permissions는 기본적으로 read-only. 필요 시 최소 권한만 일시적으로 부여.
  5. 캐시/아티팩트 신뢰 경계 분리
    • 기본 브랜치, 내부 PR, 외부 PR 등 신뢰 수준에 따라 캐시 키를 분리.
    • 신뢰 경계를 넘는 캐시 공유 금지.
  6. 버전 핀 고정
    • 모든 서드파티 액션은 태그/커밋 해시 고정. 조직 표준 템플릿으로 강제.

액션 입력 파라미터 이해

  • run(필수): 샌드박스에서 실행할 커맨드(멀티라인 가능).
  • env: 샌드박스 내 추가 환경변수(한 줄당 KEY=VALUE).
  • persist-workspace-changes(기본 false): true 시 반영, 보안상 비권장.
  • disable-network(기본 false): 네트워크 차단(의존성 재현성 테스트에 유용).
  • allow-checkout-credentials(기본 false): 샌드박스에서 체크아웃 자격증명 접근 허용(비권장).
  • rootfs-image: 루트FS로 사용할 컨테이너 이미지 지정(조직 표준 베이스 이미지 적용에 유용).
300x250

실전 YAML 예시

1. 기본형(Go 테스트) – 최소권한 + 샌드박스

name: Go tests (sandboxed)
on: [push, pull_request]
permissions:
  contents: read
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          persist-credentials: false
      - uses: actions/setup-go@v5
        with:
          go-version: stable
      - uses: geomys/sandboxed-step@v1.2.0
        with:
          run: |
            go get -u -t ./...
            go test ./...

2. 의존성 재현성 검증 – 네트워크 차단

- uses: geomys/sandboxed-step@v1.2.0
  with:
    disable-network: true
    run: |
      go test ./...           # 외부 통신 없이도 빌드/테스트가 재현되는지 확인

네트워크가 필요하다면 의존성 고정(락파일/벤더링) 정책을 강화해야 합니다.

3. 조직 표준 루트FS 사용 – 도구 내장 이미지

- uses: geomys/sandboxed-step@v1.2.0
  with:
    rootfs-image: ghcr.io/acme/security-hardened:24.04
    run: |
      ./scripts/ci.sh

정책상 요구되는 보안 스캐너, 공통 빌드체인을 루트FS에 포함해 일관성 확보.

4. (비권장) 변경 영속화가 불가피한 코드젠 단계

- uses: geomys/sandboxed-step@v1.2.0
  with:
    persist-workspace-changes: true
    run: |
      ./codegen.sh
# ⚠ 이후 단계는 워크스페이스 불신 → 같은 Job에서 민감 단계 실행 금지
#    다음 Job에서 새 checkout으로 신뢰 경계 재설정 권장

보안 운영 체크리스트

토큰/권한

  • 워크플로 permissions 기본 read-only.
  • 모든 actions/checkoutpersist-credentials: false 적용.
  • allow-checkout-credentials: false 유지(예외는 보안 승인 필요).

샌드박스 정책

  • 외부 PR/오픈소스/의존성 최신화 테스트 단계는 샌드박스 필수.
  • disable-network: true 단계 운영(락파일·재현성 검증).
  • persist-workspace-changes: true 금지(예외 시 잡 분리·재체크아웃).

캐시/아티팩트

  • 신뢰 경계(기본 브랜치·내부 PR·외부 PR)별 캐시 키 분리.
  • 경계 간 캐시 공유 금지 정책 문서화.

서드파티 액션 통제

  • 액션 버전 핀 고정(SHA/태그).
  • 필요 시 네트워크/비밀 유출 감시 액션 병행.

거버넌스

  • Org 레벨 Required Workflow로 강제.
  • PR 템플릿에 샌드박스 체크/예외 사유 항목 추가.
  • 예외 승인(기간·사유·대응책) 기록·감사.

도입 시나리오

  1. 외부 PR 검증 파이프라인
    • 빌드/테스트/린트/정적분석을 전부 샌드박스에서 실행.
    • 캐시 공유 금지, 최소권한, 체크아웃 자격증명 제거.
  2. 의존성 최신화 트랙
    • 스케줄러로 최신 버전 호환성 테스트를 샌드박스에서 수행.
    • 실패 시 알림만 발생(기본 브랜치에는 영향 없음).
  3. 보안 테스트 트랙
    • disable-network: true로 오프라인 재현성 평가.
    • 예상치 못한 외부 다운로드·스크립트 호출 탐지.
  4. 서드파티 코드/코드젠 격리
    • 신뢰도 낮은 생성 코드/도구는 항상 샌드박스에서 실행.

포인트 & 한계

  • 장점: 단계 격리 강화, 영향 범위 축소, 외부 입력(코드·의존성) 검증 안정성 향상, 표준 루트FS 기반 재현성 확보.
  • 한계: 시스템콜 가상화로 인한 성능 오버헤드, 일부 저수준 기능(Docker-in-Docker, 특정 커널 기능) 제약, GPU 등 특수자원 활용 제한 가능.
  • 운영 팁: 보안 위험도가 높은 경로(외부 PR, 의존성 업데이트)에 우선 적용하고, 빌드 병렬성·캐시 전략으로 성능 체감을 완화합니다.

트러블슈팅 가이드

  • 샌드박스 단계에서 토큰 관련 오류
    • 체크아웃 단계에 persist-credentials: false가 누락되었는지 확인.
  • 네트워크 차단으로 빌드 실패
    • 락파일 고정, 벤더링, 내부 미러/프록시 전략 재점검.
  • 성능 저하
    • 샌드박스 적용 대상을 고위험 단계로 한정하고, 캐시·매트릭스 전략으로 보완.
  • 영속화 필요 단계와 충돌
    • 해당 단계 이후를 다른 Job으로 분리하고 재체크아웃으로 신뢰 경계 재수립.

 

이 샌드박스 액션은 “한 단계에서 발생한 문제를 다음 단계/러너 전체로 번지지 않게 하는 마지막 안전벨트”입니다. 위의 운영 원칙·YAML 예시·체크리스트를 반영하면, 외부 코드와 최신 의존성에 대한 공급망 리스크를 실무적으로 낮출 수 있습니다.

728x90
그리드형(광고전용)

댓글