Devliner

GitHub Actions에서 Resource not accessible 오류가 날 때 GITHUB_TOKEN 권한 확인법

GitHub Actions에서 Resource not accessible 오류가 날 때 GITHUB_TOKEN 권한 확인법 대표 이미지

도입: GitHub Actions에서 Resource not accessible 오류가 날 때 GITHUB_TOKEN 권한 확인법 한 줄 정의

GitHub Actions 워크플로우가 리포지토리 리소스에 접근하려 할 때 "Resource not accessible by integration" 오류가 발생하면, 자동으로 생성되는 GITHUB_TOKEN의 권한 범위(permissions)가 해당 작업을 수행하기에 부족하다는 신호다. 이 문제를 해결하려면 워크플로우 파일에서 permissions 블록을 명시적으로 선언하거나, 리포지토리 설정에서 GITHUB_TOKEN의 기본 권한 수준을 조정해야 한다.

GitHub Actions에서 Resource not accessible 오류가 날 때 GITHUB_TOKEN 권한 확인법 핵심 항목

1. GITHUB_TOKEN의 정의와 자동 생성 원리

정의: GITHUB_TOKEN은 GitHub Actions 워크플로우가 실행될 때마다 GitHub이 자동으로 생성하는 임시 인증 토큰이다. 워크플로우가 종료되면 자동으로 만료되며, 코드 체크아웃, 이슈 생성, Pull Request 댓글 작성 등 GitHub API 작업에 사용된다.

원리: 워크플로우 실행 시점에 GitHub은 해당 리포지토리와 워크플로우 컨텍스트를 기반으로 토큰을 발급한다. 토큰의 권한 범위는 리포지토리 설정의 "Workflow permissions" 기본값과 워크플로우 YAML 파일 내 permissions 블록에 의해 결정된다. permissions 블록이 없으면 리포지토리 기본 설정을 따르며, 2023년 2월 이후 생성된 리포지토리는 기본적으로 "Read repository contents and packages permissions"로 제한된다.

예시: 워크플로우에서 actions/checkout@v3을 사용해 코드를 내려받는 작업은 읽기 권한만 필요하므로 기본 설정으로 실행된다. 하지만 gh pr comment 명령으로 Pull Request에 댓글을 달려면 pull-requests: write 권한이 필요하며, 이 권한이 없으면 "Resource not accessible" 오류가 발생한다.

오해: "GITHUB_TOKEN은 항상 모든 작업을 수행할 수 있다"는 생각은 잘못됐다. 보안 강화를 위해 GitHub은 최소 권한 원칙(principle of least privilege)을 적용하며, 필요한 권한만 명시적으로 부여하도록 권장한다.

2. permissions 블록 선언 방법

정의: permissions 블록은 워크플로우 YAML 파일에서 GITHUB_TOKEN이 접근할 수 있는 리소스 범위를 명시하는 설정이다. 워크플로우 최상위 레벨 또는 개별 job 레벨에서 선언할 수 있다.

원리: permissions 블록은 키-값 쌍으로 구성되며, 키는 리소스 유형(contents, issues, pull-requests, packages 등), 값은 권한 수준(read, write, none)이다. 워크플로우 레벨에서 선언하면 모든 job에 적용되고, job 레벨에서 선언하면 해당 job만 영향을 받는다. 명시되지 않은 권한은 자동으로 none으로 설정된다.

예시:

name: Example Workflow
on: [push]

permissions:
  contents: read
  pull-requests: write

jobs:
  comment:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Comment on PR
        run: gh pr comment ${{ github.event.pull_request.number }} --body "Build completed"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

이 예시에서는 코드 읽기와 Pull Request 쓰기 권한을 명시했다. gh pr comment 명령이 정상 작동하려면 pull-requests: write가 필수다.

오해: "permissions 블록을 추가하면 보안이 약해진다"는 우려는 오히려 반대다. 필요한 권한만 명시함으로써 불필요한 접근을 차단하고, 워크플로우가 어떤 작업을 수행할 수 있는지 명확히 문서화할 수 있다.

3. 리포지토리 기본 권한 설정 확인

정의: 리포지토리 설정의 "Actions > General > Workflow permissions"는 permissions 블록이 없는 워크플로우에 적용되는 GITHUB_TOKEN의 기본 권한 수준을 결정한다.

원리: 이 설정에는 두 가지 옵션이 있다. "Read repository contents and packages permissions"는 읽기 전용 권한만 부여하며, "Read and write permissions"는 contents, packages, metadata 등에 대한 쓰기 권한까지 포함한다. 2023년 2월 이후 생성된 리포지토리는 보안상 읽기 전용이 기본값이다.

예시: 리포지토리 설정이 읽기 전용인 상태에서 워크플로우가 릴리스 노트를 자동 생성하려 하면 "Resource not accessible" 오류가 발생한다. 이 경우 워크플로우 파일에 permissions: contents: write를 추가하거나, 리포지토리 설정을 "Read and write"로 변경해야 한다. 보안 관점에서는 워크플로우별로 필요한 권한만 명시하는 첫 번째 방법이 권장된다.

오해: "리포지토리 설정을 읽기/쓰기로 바꾸면 모든 문제가 해결된다"는 생각은 위험하다. 이 설정은 모든 워크플로우에 영향을 미치므로, 악의적인 Pull Request가 워크플로우를 트리거할 경우 의도하지 않은 쓰기 작업이 실행될 수 있다.

4. 권한 범위별 사용 사례

정의: GitHub Actions에서 사용 가능한 권한 범위는 actions, checks, contents, deployments, issues, packages, pull-requests, repository-projects, security-events, statuses 등 다양하며, 각각 특정 API 엔드포인트와 연결된다.

원리: 각 권한 범위는 GitHub REST API 및 GraphQL API의 특정 리소스에 대한 접근을 제어한다. 예를 들어 contents: write는 파일 생성/수정, 브랜치 생성, 태그 푸시를 허용하고, issues: write는 이슈 생성/수정/닫기를 가능하게 한다. 워크플로우가 수행하는 작업에 따라 필요한 권한을 조합해야 한다.

예시:

  • 자동 릴리스 생성: contents: write (태그 푸시 및 릴리스 생성)
  • 테스트 결과를 Pull Request에 댓글로 추가: pull-requests: write
  • Docker 이미지를 GitHub Container Registry에 푸시: packages: write
  • 보안 취약점 스캔 결과 업로드: security-events: write

오해: "모든 권한을 write로 설정하면 편하다"는 접근은 보안 원칙에 어긋난다. 공격자가 워크플로우를 조작할 경우 리포지토리 전체가 위험에 노출될 수 있다.

핵심 원리 정리

GITHUB_TOKEN 권한 문제는 최소 권한 원칙과 명시적 선언이라는 두 가지 보안 원칙에서 비롯된다. GitHub은 워크플로우가 필요한 최소한의 권한만 갖도록 기본값을 제한하며, 개발자가 permissions 블록을 통해 필요한 권한을 명시적으로 선언하도록 유도한다. 오류 메시지가 나타나면 워크플로우가 수행하려는 작업을 파악하고, 해당 작업에 필요한 권한 범위를 YAML 파일에 추가하면 된다. 리포지토리 전체 설정을 변경하기보다는 워크플로우별로 권한을 관리하는 것이 보안상 안전하다.

흔한 오해

"GITHUB_TOKEN 오류는 토큰이 만료돼서 발생한다": GITHUB_TOKEN은 워크플로우 실행 시마다 새로 생성되므로 만료 문제는 발생하지 않는다. 오류의 원인은 권한 부족이다.

"Personal Access Token으로 대체하면 모든 문제가 해결된다": PAT는 더 넓은 권한을 가질 수 있지만, 유출 위험이 크고 만료 관리가 필요하다. GITHUB_TOKEN의 권한 범위를 올바르게 설정하는 것이 더 안전하다.

"permissions 블록은 공개 리포지토리에만 필요하다": 비공개 리포지토리도 2023년 2월 이후 생성됐다면 기본 권한이 읽기 전용이므로, 쓰기 작업을 수행하려면 permissions 블록이 필요하다.

"워크플로우 파일 수정 없이 리포지토리 설정만 바꾸면 된다": 리포지토리 설정 변경은 모든 워크플로우에 영향을 미치므로, 특정 워크플로우만 권한이 필요한 경우 YAML 파일에 permissions를 명시하는 것이 정확하다.

이해 확인 요약

GitHub Actions에서 "Resource not accessible" 오류는 GITHUB_TOKEN의 권한 범위가 워크플로우가 수행하려는 작업에 필요한 수준에 미치지 못할 때 발생한다. 해결 방법은 워크플로우 YAML 파일에 permissions 블록을 추가해 필요한 권한(contents, pull-requests, packages 등)을 명시하거나, 리포지토리 설정에서 기본 권한 수준을 조정하는 것이다. 보안 측면에서는 워크플로우별로 최소한의 권한만 부여하는 것이 권장되며, 각 권한 범위가 어떤 API 작업과 연결되는지 이해하면 오류를 빠르게 해결할 수 있다.

참고 자료

  • GitHub
  • Actions에서
  • Resource

관련 글

전체 보기