> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# GitHub Actions의 핀 고정과 보안

> 패키지의 공급망 공격 대책으로서, GitHub Actions의 의존 관계를 버전에서 SHA 해시로 핀 고정하는 방법을, Dependabot의 자동 갱신 전략을 포함하여 해설합니다.

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

<Info>
  이 페이지는 [패키지 개발의 기초](/ko/advanced/package-development)의 자매 페이지입니다. GitHub Actions의 기본적인 사용 방법을 전제로 하고 있습니다.
</Info>

## GitHub Actions의 보안 리스크

### 태그 기반 참조의 위험성

일반적으로, GitHub Actions는 다음과 같이 태그로 참조됩니다.

```yaml theme={null}
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
```

이 접근 방식의 문제점:

* **태그는 이동 가능** — 태그는 삭제·재작성되어도 같은 이름을 가질 수 있습니다
* **변조 리스크** — 리포지토리 소유자의 계정 탈취로 악의 있는 코드를 주입 가능
* **공급망 공격** — 의존하는 액션이 공격받으면, 여러분의 워크플로우가 침해됩니다

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

[laravel/laravel](https://github.com/laravel/laravel)과 [laravel/framework](https://github.com/laravel/framework)에서는, 모든 액션을 커밋 해시(SHA)로 핀 고정하고 있습니다.

```yaml theme={null}
# セキュアな参照方法
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
```

## 핀 고정의 구현 전략

### 스텝 1: Dependabot 설정 파일 작성

패키지 리포지토리에 `.github/dependabot.yml`을 작성합니다. Laravel의 파일을 그대로 복사할 수 있습니다.

```yaml theme={null}
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](https://github.com/suzuki-shunsuke/pinact) 등의 도구로 자동화할 수 있습니다.

#### pinact 도구를 사용한 자동화

```shell theme={null}
# ワークフロー内のアクションをSHAにピン留め
pinact run
```

#### 수동에 의한 변경

`pinact`가 이용할 수 없는 경우에는, GitHub의 [Lookup latest version](https://github.com/actions/checkout) 페이지에서 각 액션의 커밋 SHA를 조사하여 수동으로 치환합니다.

```yaml theme={null}
# 変更前
- 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`의 설정에 기반하여, 다른 갱신 전략을 적용합니다.

### 핀 고정되지 않은 액션

```yaml theme={null}
# ピン留め前
- uses: actions/checkout@v4
```

Dependabot의 갱신: **버전 범위를 새 버전으로 갱신**

```yaml theme={null}
# Dependabotが作成するPR
- uses: actions/checkout@v5
```

이 접근 방식은 편의성 중시로, 태그의 이동에 대응할 수 있지만, 보안 리스크는 남습니다.

### 핀 고정된 액션

```yaml theme={null}
# ピン留め後
- uses: actions/checkout@a5ac7e51b41094c7fcab2042361574b0021804ab  # v4
```

Dependabot의 갱신: **새 버전의 커밋 해시로 갱신**

```yaml theme={null}
# Dependabotが作成するPR
- uses: actions/checkout@f1d3225b54b677ba3e72df8c464cb6cf6dc1aebf  # v4
```

이 접근 방식은 가장 안전합니다. 새 버전이라도, 커밋 해시의 참조이므로 변조에 강합니다.

## 워크플로우의 구현 예

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

```yaml theme={null}
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에서 갱신됩니다.

```yaml theme={null}
groups:
  github-actions:
    patterns:
      - "*"
```

전체 액션 갱신을 하나의 PR로 정리함으로써, 머지 횟수를 줄일 수 있습니다.

## 핀 고정의 장점과 단점

### 장점

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

### 단점

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

## 보안 감사 체크리스트

새 패키지 프로젝트를 시작하는 경우의 체크리스트입니다.

<AccordionGroup>
  <Accordion title="초기 셋업">
    * [ ] `.github/dependabot.yml`을 작성
    * [ ] 기존 액션 전부를 SHA로 핀 고정
    * [ ] `pinact` 또는 수동으로 확인 완료
    * [ ] 워크플로우가 정상적으로 실행되는 것을 확인
  </Accordion>

  <Accordion title="정기 유지보수">
    * [ ] Dependabot의 갱신 PR을 주 1회 이상 리뷰
    * [ ] 보안 갱신은 우선적으로 머지
    * [ ] 새 액션 추가 시에는 반드시 SHA로 참조
    * [ ] 월에 1회, 전 워크플로우의 상태를 확인
  </Accordion>

  <Accordion title="감사">
    * [ ] 모든 액션 참조가 SHA로 되어 있는지 확인
    * [ ] Dependabot이 활성화되어 있는지 확인
    * [ ] 과거 6개월의 Dependabot의 PR이 전부 머지되어 있는지 확인
  </Accordion>
</AccordionGroup>

## 관련 페이지

<Columns cols={2}>
  <Card title="패키지 개발의 기초" icon="box" href="/ko/advanced/package-development">
    서비스 프로바이더를 핵심으로 한 Laravel 패키지의 개발 방법을 해설합니다.
  </Card>

  <Card title="패키지의 버전 호환성 관리" icon="tag" href="/ko/advanced/package-versioning">
    Laravel의 메이저 버전 업그레이드에의 패키지 대응 전략을 해설합니다.
  </Card>
</Columns>


## Related topics

- [MCP](/ko/packages/laravel-copilot-sdk/mcp.md)
- [세션 재개](/ko/packages/laravel-copilot-sdk/resume.md)
- [GitHub Actions - GitHub Copilot SDK for Laravel](/ko/packages/laravel-copilot-sdk/github-actions.md)
- [Plugin Directories](/ko/packages/laravel-copilot-sdk/plugin-directories.md)
- [봇 튜토리얼 - Laravel Bluesky](/ko/packages/laravel-bluesky/bot-tutorial.md)
