메인 콘텐츠로 건너뛰기
GitHub의 액션에 대한 공격이나 변조 리스크에 대응하기 위해, 공식 Laravel 프로젝트에서도 채용하고 있는 보안 대책이 GitHub Actions의 핀 고정(pinning)입니다. 이 페이지에서는, 패키지 개발자가 구현해야 할 보안 대책을 실전적으로 해설합니다.
이 페이지는 패키지 개발의 기초의 자매 페이지입니다. GitHub Actions의 기본적인 사용 방법을 전제로 하고 있습니다.

GitHub Actions의 보안 리스크

태그 기반 참조의 위험성

일반적으로, GitHub Actions는 다음과 같이 태그로 참조됩니다.
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
이 접근 방식의 문제점:
  • 태그는 이동 가능 — 태그는 삭제·재작성되어도 같은 이름을 가질 수 있습니다
  • 변조 리스크 — 리포지토리 소유자의 계정 탈취로 악의 있는 코드를 주입 가능
  • 공급망 공격 — 의존하는 액션이 공격받으면, 여러분의 워크플로우가 침해됩니다

공식 Laravel 프로젝트에서의 대응

laravel/laravellaravel/framework에서는, 모든 액션을 커밋 해시(SHA)로 핀 고정하고 있습니다.
# セキュアな参照方法
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4

핀 고정의 구현 전략

스텝 1: Dependabot 설정 파일 작성

패키지 리포지토리에 .github/dependabot.yml을 작성합니다. Laravel의 파일을 그대로 복사할 수 있습니다.
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    cooldown:
      default-days: 5
    groups:
      github-actions:
        patterns:
          - "*"
이 파일은 이하의 역할을 담당합니다:
  • 자동 스캔 — GitHub Actions의 새 버전을 스캔
  • 자동 PR 작성 — 갱신이 이용 가능한 경우, 업데이트 PR을 자동 작성
  • 갱신 방법의 제어 — 핀 고정되지 않은 액션은 버전으로, 핀 고정된 액션은 SHA로 갱신

스텝 2: 기존 액션을 SHA로 핀 고정

기존 워크플로우 내의 모든 액션 참조를 SHA 해시로 변경합니다. 이것은 pinact 등의 도구로 자동화할 수 있습니다.

pinact 도구를 사용한 자동화

# ワークフロー内のアクションをSHAにピン留め
pinact run

수동에 의한 변경

pinact가 이용할 수 없는 경우에는, GitHub의 Lookup latest version 페이지에서 각 액션의 커밋 SHA를 조사하여 수동으로 치환합니다.
# 変更前
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
  with:
    php-version: ${{ matrix.php }}

# 変更後
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
- uses: shivammathur/setup-php@0a92e4568cab5c87b7175192630661408458a086  # v2
  with:
    php-version: ${{ matrix.php }}

스텝 3: Dependabot의 설정을 활성화

.github/dependabot.yml을 리포지토리에 커밋하여 푸시하면, Dependabot이 자동적으로 스캔을 시작합니다.

Dependabot에 의한 자동 갱신 메커니즘

Dependabot은 dependabot.yml의 설정에 기반하여, 다른 갱신 전략을 적용합니다.

핀 고정되지 않은 액션

# ピン留め前
- uses: actions/checkout@v4
Dependabot의 갱신: 버전 범위를 새 버전으로 갱신
# Dependabotが作成するPR
- uses: actions/checkout@v5
이 접근 방식은 편의성 중시로, 태그의 이동에 대응할 수 있지만, 보안 리스크는 남습니다.

핀 고정된 액션

# ピン留め後
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
Dependabot의 갱신: 새 버전의 커밋 해시로 갱신
# Dependabotが作成するPR
- uses: actions/checkout@f1d3225b54b677ba3e72df8c464cb6cf6dc1aebf  # v4
이 접근 방식은 가장 안전합니다. 새 버전이라도, 커밋 해시의 참조이므로 변조에 강합니다.

워크플로우의 구현 예

여러 워크플로우에서 액션을 사용하는 경우의 완전한 예입니다.
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    strategy:
      fail-fast: false
      matrix:
        php: [8.2, 8.3, 8.4]
        laravel: ["^12.0", "^13.0"]

    steps:
      - uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
        with:
          fetch-depth: 0

      - name: Setup PHP
        uses: shivammathur/setup-php@0a92e4568cab5c87b7175192630661408458a086  # v2
        with:
          php-version: ${{ matrix.php }}
          extensions: dom, curl, libxml, mbstring, zip, intl, sqlite3
          coverage: none

      - name: Install dependencies
        run: |
          composer require "laravel/framework:${{ matrix.laravel }}" \
                           --no-interaction --no-update
          composer update --prefer-dist --no-interaction

      - name: Run tests
        run: vendor/bin/pest

  lint:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4

      - name: Setup PHP
        uses: shivammathur/setup-php@0a92e4568cab5c87b7175192630661408458a086  # v2
        with:
          php-version: "8.4"
          extensions: dom, curl, libxml, mbstring, zip
          coverage: none

      - name: Install dependencies
        run: composer install --prefer-dist --no-interaction

      - name: Run static analysis
        run: vendor/bin/phpstan

Dependabot의 갱신 PR 대응

Dependabot이 작성하는 업데이트 PR은 이하와 같이 대응합니다.

단일 액션의 갱신 PR

Bump shivammathur/setup-php from v1 to v2
이러한 단순한 업데이트는 이하와 같이 대응:
  1. 워크플로우 실행 결과를 확인
  2. 파괴적 변경이 없는지 확인
  3. 머지하여 완료

보안 업데이트 PR

[SECURITY] Bump actions/checkout to a5ac7e51b41094c7fcab2042361574b0021804ab
보안 수정에 관한 갱신은 우선적으로 머지합니다.

여러 액션의 그룹 갱신

dependabot.yml에서 groups를 설정하고 있는 경우, 여러 액션이 한 번의 PR에서 갱신됩니다.
groups:
  github-actions:
    patterns:
      - "*"
전체 액션 갱신을 하나의 PR로 정리함으로써, 머지 횟수를 줄일 수 있습니다.

핀 고정의 장점과 단점

장점

장점설명
공급망 공격 대책특정 커밋 해시를 참조하므로, 액션의 변조에 대항할 수 있음
감사 가능성각 액션이 언제 어느 버전에서 갱신되었는지를 추적할 수 있음
명시적인 갱신Dependabot이 갱신을 제안하는 형식이므로, 사람의 리뷰를 반드시 경유함
재현성같은 커밋 해시로 실행하면, 완전히 같은 환경이 재현됨

단점

단점대처 방법
수작업의 초기 셋업pinact 도구로 자동화
갱신 관리의 수고 증가Dependabot으로 자동 PR 작성하므로, 구현 비용 최소화
가독성이 떨어짐코멘트로 버전을 병기하여 가독성 확보

보안 감사 체크리스트

새 패키지 프로젝트를 시작하는 경우의 체크리스트입니다.
  • .github/dependabot.yml을 작성
  • 기존 액션 전부를 SHA로 핀 고정
  • pinact 또는 수동으로 확인 완료
  • 워크플로우가 정상적으로 실행되는 것을 확인
  • Dependabot의 갱신 PR을 주 1회 이상 리뷰
  • 보안 갱신은 우선적으로 머지
  • 새 액션 추가 시에는 반드시 SHA로 참조
  • 월에 1회, 전 워크플로우의 상태를 확인
  • 모든 액션 참조가 SHA로 되어 있는지 확인
  • Dependabot이 활성화되어 있는지 확인
  • 과거 6개월의 Dependabot의 PR이 전부 머지되어 있는지 확인

관련 페이지

패키지 개발의 기초

서비스 프로바이더를 핵심으로 한 Laravel 패키지의 개발 방법을 해설합니다.

패키지의 버전 호환성 관리

Laravel의 메이저 버전 업그레이드에의 패키지 대응 전략을 해설합니다.
마지막 수정일 2026년 7월 13일