728x90

왜 샌드박스가 필요한가
- 문제: GitHub Actions는 기본적으로 같은 VM 안에서 여러 step이 실행됩니다. 한 단계에서 악성 코드가 실행되면 다음 단계나 캐시, 러너 환경까지 영향을 줄 수 있습니다. 또한 캐시 토큰 오용(포이즈닝)과 체크아웃 토큰 노출 등 공급망(Supply Chain) 리스크가 현실적인 위협입니다.
- 해결: 각 명령을 gVisor 샌드박스 안에서 실행합니다.
- 루트 파일시스템: Ubuntu 24.04 유사 환경.
- 툴 디렉터리(RUNNER_TOOL_CACHE): 읽기 전용 마운트.
- 워크스페이스(GITHUB_WORKSPACE): 오버레이(기본 비영속, 변경사항이 호스트에 자동 반영되지 않음).
- 효과: 단계 간 격리 강화, 캐시/토큰 남용에 따른 피해 확산 억제, 외부 PR/오픈소스 의존성 검증 시 안전성 향상.
위협 모델과 보안 목표
- 위협 시나리오
- 외부 PR 코드가 악의적 스크립트를 수행해 이후 단계 환경을 오염.
- 캐시 키를 악용해 악성 바이너리나 스크립트를 주입.
- 체크아웃으로 내려온 토큰·자격증명이 워크스페이스에 남아 유출.
- 보안 목표
- 단계별 실행 환경을 경량 격리(샌드박스).
- 워크스페이스 변경의 의도적 영속화만 허용(기본 비영속).
- 자격증명 최소화와 네트워크 통제로 공급망 공격면 축소.
- 캐시/아티팩트의 신뢰 경계 분리.
필수 운영 원칙
- 체크아웃 토큰 남김 금지
actions/checkout은 항상persist-credentials: false.- 워크스페이스에 자격증명을 남기지 않는 것이 샌드박스 효과를 유지하는 핵심입니다.
- 워크스페이스 비영속 유지
persist-workspace-changes: false(기본): 샌드박스 내 변경사항이 호스트로 반영되지 않음.- 부득이하게 영속화가 필요하면, 해당 단계 이후는 신뢰 불가 구간으로 취급하고 잡(Job) 분리 또는 재체크아웃으로 경계 재수립.
- 네트워크 최소화
- 재현성/락파일 무결성 검증 단계는
disable-network: true로 외부 다운로드를 차단. - 네트워크가 필요한 설치·빌드는 별도 단계/잡에서 수행.
- 재현성/락파일 무결성 검증 단계는
- 권한 최소화
- 워크플로
permissions는 기본적으로 read-only. 필요 시 최소 권한만 일시적으로 부여.
- 워크플로
- 캐시/아티팩트 신뢰 경계 분리
- 기본 브랜치, 내부 PR, 외부 PR 등 신뢰 수준에 따라 캐시 키를 분리.
- 신뢰 경계를 넘는 캐시 공유 금지.
- 버전 핀 고정
- 모든 서드파티 액션은 태그/커밋 해시 고정. 조직 표준 템플릿으로 강제.
액션 입력 파라미터 이해
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/checkout에persist-credentials: false적용. -
allow-checkout-credentials: false유지(예외는 보안 승인 필요).
샌드박스 정책
- 외부 PR/오픈소스/의존성 최신화 테스트 단계는 샌드박스 필수.
-
disable-network: true단계 운영(락파일·재현성 검증). -
persist-workspace-changes: true금지(예외 시 잡 분리·재체크아웃).
캐시/아티팩트
- 신뢰 경계(기본 브랜치·내부 PR·외부 PR)별 캐시 키 분리.
- 경계 간 캐시 공유 금지 정책 문서화.
서드파티 액션 통제
- 액션 버전 핀 고정(SHA/태그).
- 필요 시 네트워크/비밀 유출 감시 액션 병행.
거버넌스
- Org 레벨 Required Workflow로 강제.
- PR 템플릿에 샌드박스 체크/예외 사유 항목 추가.
- 예외 승인(기간·사유·대응책) 기록·감사.
도입 시나리오
- 외부 PR 검증 파이프라인
- 빌드/테스트/린트/정적분석을 전부 샌드박스에서 실행.
- 캐시 공유 금지, 최소권한, 체크아웃 자격증명 제거.
- 의존성 최신화 트랙
- 스케줄러로 최신 버전 호환성 테스트를 샌드박스에서 수행.
- 실패 시 알림만 발생(기본 브랜치에는 영향 없음).
- 보안 테스트 트랙
disable-network: true로 오프라인 재현성 평가.- 예상치 못한 외부 다운로드·스크립트 호출 탐지.
- 서드파티 코드/코드젠 격리
- 신뢰도 낮은 생성 코드/도구는 항상 샌드박스에서 실행.
포인트 & 한계
- 장점: 단계 격리 강화, 영향 범위 축소, 외부 입력(코드·의존성) 검증 안정성 향상, 표준 루트FS 기반 재현성 확보.
- 한계: 시스템콜 가상화로 인한 성능 오버헤드, 일부 저수준 기능(Docker-in-Docker, 특정 커널 기능) 제약, GPU 등 특수자원 활용 제한 가능.
- 운영 팁: 보안 위험도가 높은 경로(외부 PR, 의존성 업데이트)에 우선 적용하고, 빌드 병렬성·캐시 전략으로 성능 체감을 완화합니다.
트러블슈팅 가이드
- 샌드박스 단계에서 토큰 관련 오류
- 체크아웃 단계에
persist-credentials: false가 누락되었는지 확인.
- 체크아웃 단계에
- 네트워크 차단으로 빌드 실패
- 락파일 고정, 벤더링, 내부 미러/프록시 전략 재점검.
- 성능 저하
- 샌드박스 적용 대상을 고위험 단계로 한정하고, 캐시·매트릭스 전략으로 보완.
- 영속화 필요 단계와 충돌
- 해당 단계 이후를 다른 Job으로 분리하고 재체크아웃으로 신뢰 경계 재수립.
이 샌드박스 액션은 “한 단계에서 발생한 문제를 다음 단계/러너 전체로 번지지 않게 하는 마지막 안전벨트”입니다. 위의 운영 원칙·YAML 예시·체크리스트를 반영하면, 외부 코드와 최신 의존성에 대한 공급망 리스크를 실무적으로 낮출 수 있습니다.
728x90
그리드형(광고전용)
댓글