DevOps 관점에서 GitHub 자동화를 “안전하고, 감사 가능하며, 세분화된 권한”으로 운영하려면 GitHub App이 사실상 표준입니다. 아래에 개념부터, GitHub Token(특히 Fine-grained PAT)과의 차이, 조직에서의 도입 패턴, 실전 코드와 GitHub Actions 예시까지 “step-by-step”으로 정리했습니다.
1) GitHub Apps란?
- GitHub 리소스(리포지토리, 이슈, 체크런 등)에 접근하는 1급(First-class) 통합 방식
- 세분화된 권한(permissions) 과 짧은 수명의 토큰(short-lived) 을 사용해 보안 수준이 높음
- “앱을 조직/개인 계정에 설치(installation) → 설치가 허용된 리포/조직 범위 안에서만 작동” 구조
- OAuth App과 비교해 보안/운영 측면에서 권장되는 방식(권한/범위/토큰 모델이 더 안전) GitHub Docs
핵심 구성 요소
- App 등록: App ID, Client ID, Private Key(PEM) 생성
- JWT: App로 인증하기 위해 RS256으로 서명한 JSON Web Token 생성(만료 매우 짧음) GitHub Docs
- Installation Access Token: 특정 설치(organization/user 설치 단위)에 대해 최대 1시간짜리 단기 토큰 발급 후 API 호출에 사용 GitHub Docs
참고: GitHub Actions의 기본 GITHUB_TOKEN도 내부적으로 “GitHub App 설치 토큰”입니다. 그래서 권한을 워크플로우에서 조절할 수 있고(permissions 섹션) 자동으로 짧은 주기로 재발급됩니다. GitHub Docs+1
2) GitHub Token(PAT)과의 차이
| 항목 | GitHub App | Fine-grained PAT | (참고) Classic PAT |
| 발급 주체 | 앱(머신 아이덴티티) | 사용자(사람) | 사용자(사람) |
| 권한 범위 | 리포지토리/조직 단위로 세밀하게 선택, 이벤트 별 권한 | 리포지토리/조직 단위로 세밀 설정 가능(기본 권장) | 범위가 넓고(스코프) 과권한 위험 |
| 토큰 수명 | 단기(≈1시간), 자동 재발급 전제 | 장기(만료일 설정) 가능 | 장기(만료 선택적), 보안 취약 |
| 회수/격리 | 설치 단위로 즉시 철회 가능 | 특정 리포/조직 권한만 철회 가능 | 조직 전반 영향 클 수 있음 |
| 주 사용 시나리오 | CI/CD, 봇 계정, 자동화, 조직 전역 도구 | 개인 개발/로컬 자동화, 제한된 봇 | 레거시/비권장 |
| 권장도 | 조직/프로덕션 자동화 1순위 | 개인용/소규모 자동화에서 유용 | 가능하면 미사용 권장 |
- GitHub는 가능하면 fine-grained PAT(클래식 대신)를, 그리고 조직 통합/자동화에는 GitHub App을 권장합니다. GitHub Docs
3) 권한 모델(왜 App이 안전한가)
- 권한을 액션 단위로 부여(예: “Contents: read”, “Issues: write”, “Pull requests: read”)
- 설치 시 리포지토리 선택으로 범위를 최소화(조직 전체가 아닌 특정 리포만)
- 토큰은 짧은 수명(기본 1시간)이라 유출 시 피해창이 작음
- 필요 시 설치 단위 철회로 영향 범위를 빠르게 차단 가능 GitHub Docs
4) 언제 GitHub App, 언제 PAT?
GitHub App 사용을 강하게 권장:
- 조직/프로덕션 CI/CD·배포·레이블러·코드정리 봇
- 여러 리포지토리에 통합 권한으로 자동화 작업
- 감사/회수/Least Privilege가 중요한 환경
Fine-grained PAT 사용이 실용적인 경우:
- 개인 로컬 스크립트, 단일 리포 한정 자동화
- 일시적 내부 작업(예: 툴 테스트)
- 조직 정책상 App 등록이 어려운 상황(임시)
(둘 다 가능하지만) Classic PAT은 가급적 사용 자제. GitHub Docs
5) Step-by-Step: GitHub App 만들기 & 토큰 발급
5-1. App 등록
- Settings → Developer settings → GitHub Apps → New GitHub App
- 앱 이름, Homepage URL, Webhook URL(선택) 설정
- Repository/Organization 권한을 최소 권한으로 체크
- Private key(PEM) 다운로드(메모리 금고/Secrets Manager에 저장)
5-2. JWT 생성(서버 측)
App로 인증하려면 먼저 JWT를 만들어 일부 App 전용 API에 접근합니다. (예: 설치 나열/조회)
Node.js (JWT 생성 & 설치 토큰 발급)
import { createAppAuth } from "@octokit/auth-app";
import { Octokit } from "octokit";
const appId = process.env.GH_APP_ID; // e.g. "123456"
const privateKey = process.env.GH_APP_KEY_PEM; // PEM contents
const installationId = process.env.GH_INSTALLATION_ID;
const appOctokit = new Octokit({
authStrategy: createAppAuth,
auth: { appId, privateKey }
});
// 1) 설치 토큰 발급
const { token } = await appOctokit.auth({
type: "installation",
installationId
});
// 2) 설치 토큰으로 API 호출
const octokit = new Octokit({ auth: token });
const { data: repo } = await octokit.request("GET /repos/{owner}/{repo}", {
owner: "acme", repo: "infra"
});
console.log(repo.full_name);
Octokit은 JWT 생성/토큰 갱신을 자동화해 App 인증을 쉽게 해줍니다. GitHub Docs+1
cURL (직접 REST 사용)
# 1) JWT는 서버에서 RS256으로 생성 (만료 ~10분 이내 권장)
JWT="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...."
# 2) 설치 토큰 발급 (1시간 유효)
curl -s -X POST \\
-H "Authorization: Bearer $JWT" \\
-H "Accept: application/vnd.github+json" \\
<https://api.github.com/app/installations/INSTALLATION_ID/access_tokens>
토큰 발급 엔드포인트 및 JWT 규격은 공식 문서 참조. GitHub Docs
6) GitHub Actions에서 GitHub App 쓰는 법(가장 깔끔한 패턴)
조직 전반에서 많이 쓰는 패턴은 GitHub-owned 액션을 이용해 App 토큰을 만들고 그 토큰으로 gh, octokit, git을 구동하는 것입니다.
name: use-github-app
on:
workflow_dispatch:
jobs:
demo:
runs-on: ubuntu-latest
permissions:
# 최소 권한 원칙: 필요한 것만 열기
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
# GitHub 공식 액션으로 설치 토큰 생성
- name: Create installation token
id: app
uses: actions/create-github-app-token@v2
with:
app-id: ${{ vars.GH_APP_ID }}
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
# (옵션) installation-retrieval-method: id | organization | repository
# installation-id: ${{ vars.GH_INSTALLATION_ID }}
- name: Use token
env:
GH_TOKEN: ${{ steps.app.outputs.token }}
run: |
gh repo view $GITHUB_REPOSITORY --json name,defaultBranchRef
git config user.name "${{ steps.app.outputs.app-slug }}[bot]"
git config user.email "${{ steps.app.outputs.app-slug }}[bot]@users.noreply.github.com"
echo "demo" >> DEMO.txt
git add DEMO.txt
git commit -m "chore: demo commit via GitHub App"
git push origin HEAD
- 위 액션이 생성한 토큰은 App 설치 토큰(단기) 이고 필요한 권한만 사용합니다.
- 액션 레포: actions/create-github-app-token@v2(GitHub 공식) GitHub Docs
기본 GITHUB_TOKEN만으로 충분한 경우가 많지만, 조직 간/리포 간 광범위 작업이나 세밀 권한이 필요하면 App 토큰이 더 유연합니다. GitHub Docs
7) Fine-grained PAT 빠르게 이해하기(대조군)
- 사용자 개인이 발급, 리포 단위 권한과 Permission을 세밀하게 설정
- API/git(HTTPS) 모두 사용 가능. 예: 단일 리포 읽기만 허용하려면 Repository: Contents(Read) 만 부여
- GitHub는 classic 대신 fine-grained 사용을 권장합니다(가능한 경우). GitHub Docs
어떤 API는 최소한 Metadata(read) 권한을 요구합니다. 에러가 나면 최소 권한 조합을 점검하세요.
8) 운영 베스트 프랙티스(DevOps 시점)
- Least Privilege
- App 권한은 꼭 필요한 리소스에만(예: Contents: read, Pull requests: write…)
- 설치 범위를 특정 리포로 제한
- 단기 토큰 기반
- App 설치 토큰(≈1시간)을 기본으로, PAT은 로컬/개인 작업에만
- 비밀 관리
- Private Key(PEM)은 GitHub Encrypted Secrets/기관 Vault에 저장
- App 키 교체(rotate) 절차 문서화
- 분리와 감사
- 기능별 App 분리(배포용, 라벨러용, 린터용 등) → 영향 최소화
- 설치 목록/권한 변경을 주기적으로 점검
- Actions 권한 선언
- permissions: 블록으로 GITHUB_TOKEN 최소 권한화(읽기 전용 default → 필요한 단계에서 write 부여) GitHub Docs
- 내부 봇 아이덴티티
- 커밋/코멘트에 “{app-slug}[bot]”가 남아 사람과 봇 활동을 분리(감사에 유리). 관련 예시는 공식 액션 레포 참조. GitHub
9) 자주 쓰는 코드 조각
9-1. Octokit으로 App 인증(토큰 자동 갱신)
import { Octokit } from "octokit";
import { createAppAuth } from "@octokit/auth-app";
const octokit = new Octokit({
authStrategy: createAppAuth,
auth: {
appId: process.env.GH_APP_ID,
privateKey: process.env.GH_APP_KEY_PEM,
installationId: process.env.GH_INSTALLATION_ID
}
});
// 자동으로 설치 토큰 생성/갱신 후 API 호출
await octokit.request("POST /repos/{owner}/{repo}/issues", {
owner: "acme", repo: "my-service",
title: "Hello from GitHub App!"
});
9-2. Fine-grained PAT로 단순 API 호출
export GH_PAT=ghp_xxx # fine-grained PAT
curl -H "Authorization: Bearer $GH_PAT" \\
-H "Accept: application/vnd.github+json" \\
<https://api.github.com/repos/acme/my-service>
10) 의사결정 가이드(요약)
- 조직/프로덕션 자동화: GitHub App → actions/create-github-app-token으로 단기 토큰 발급해 사용
- 개인 개발/로컬 스크립트: Fine-grained PAT
- Classic PAT: 레거시/불가피한 경우만
11) 자주 묻는 질문(FAQ)
Q1. GITHUB_TOKEN vs GitHub App 토큰 차이?
- GITHUB_TOKEN은 GitHub가 워크플로우 실행 시 자동 주입하는 App 설치 토큰(레포/워크플로우 컨텍스트 한정, 권한 조절 가능).
- 별도 조직 범위 작업/여러 리포 작업/크로스 조직 권한이 필요하면 전담 GitHub App을 등록해 토큰을 만들어 쓰는 게 일반적입니다. GitHub Docs
Q2. OAuth App이랑 뭐가 달라?
- OAuth App은 주로 사용자 승인 기반(User-to-Server), GitHub App은 머신/봇 아이덴티티로 조직 운영에 적합하며 권한/토큰 모델이 더 안전합니다. GitHub Docs
Q3. Installation ID는 무엇?
- 특정 계정(조직/유저)에 App을 설치한 인스턴스의 식별자. 설치 단위로 토큰을 발급합니다. GitHub Docs
12) 참고 문서(공식)
- GitHub Apps 개요/가이드: GitHub Docs(앱 권한/설치/토큰 개념) GitHub Docs
- JWT/설치 토큰 발급: 생성 규칙·엔드포인트(REST) GitHub Docs
- Octokit로 App 인증: 설치 토큰 자동 갱신 샘플 GitHub Docs
- Actions에서 App 사용: 공식 액션 actions/create-github-app-token GitHub Docs
- GITHUB_TOKEN 가이드: 권한 모델/모범사례 GitHub Docs
- Fine-grained PAT: 개요/권장사항/권한 요구사항 GitHub Docs
마지막 한 줄 요약
- 조직 자동화/프로덕션 → GitHub App(짧은 수명 토큰, 세밀 권한, 감사/회수 용이)
- 개인 자동화/실험 → Fine-grained PAT
- Actions에서는 필요 시 actions/create-github-app-token 으로 App 토큰을 발급해 최소 권한으로 사용하세요. GitHub Docs
'DevOps' 카테고리의 다른 글
| 오픈소스 검색엔진 비교: OpenSearch vs Meilisearch vs Typesense (0) | 2025.11.06 |
|---|---|
| Argo CD에서 GitHub Apps로 보안 강화하기 (0) | 2025.10.29 |
| “Swiper is not defined”와 “Mixed Content” 오류, IIS (0) | 2025.10.17 |
| 클라우드 계정이 다른 개발 / 운영 환경의 CIDR 범위 설정 (0) | 2025.10.10 |
| [kafka] 토픽을 파티션으로 나누는 이유 (0) | 2025.09.29 |
댓글