티스토리 뷰

반응형

GitHub Webhook 서버를 GitHub App으로 진화시키는 방법

지금까지 우리는 GitHub Webhook 기반의 자동화 시스템을 구축하고, GitHub Actions와 조합한 통합 전략까지 살펴봤습니다.
이번 글에서는 한 단계 더 나아가, Webhook 서버를 GitHub App으로 전환하여 보안, 확장성, 관리 측면에서 더욱 강력한 자동화 플랫폼으로 발전시키는 방법을 소개합니다.


1. 왜 Webhook → GitHub App으로 전환해야 하는가?

항목 Webhook GitHub App

인증 방식 Secret 기반 HMAC 검증 JWT + OAuth 기반 인증
권한 제어 전체 Repository 접근 스코프 단위로 세밀한 권한 설정
다중 리포 지원 하나하나 Webhook 설정 필요 App 설치만으로 여러 리포지토리 연결 가능
API 호출 권한 PAT 필요 (보안 이슈 발생 가능) App Token으로 안전하게 API 호출 가능
유지보수 개발자 개별 관리 GitHub에서 App 단위 관리 기능 제공

💡 GitHub App은 Webhook보다 보안, 확장성, 유지보수 관점에서 더 적합한 구조입니다.


2. GitHub App이란?

GitHub App은 GitHub 리포지토리와 상호작용하기 위해 만들어진 공식적인 OAuth 기반 인증된 자동화 애플리케이션입니다.
GitHub App은 다음 기능들을 기본적으로 제공합니다:

  • 설치 기반 권한 제어
  • JWT 인증을 통한 토큰 발급
  • App 전용 Webhook URL 제공
  • 조직/개인/리포지토리 단위로 설치 가능

3. GitHub App 만들기 (Step by Step)

반응형

🔹 1단계: GitHub App 등록

  1. GitHub → Settings → Developer settings → GitHub Apps
  2. "New GitHub App" 클릭
  3. 이름, 설명, 홈페이지 URL, 콜백 URL 입력
  4. Webhook URL 등록 → 기존 Webhook 서버 주소 입력
  5. Webhook Secret 설정 (보안을 위해 필수)
  6. 원하는 권한 범위(Repository, Issues, Pull Requests 등) 선택
  7. Subscribe to events: push, pull_request, issues, project_card 등

완료되면 App ID, Client ID, Private Key (.pem) 다운로드 가능


🔹 2단계: 서버에 App 인증 추가 (JWT → Installation Token)

📌 JWT 생성 (jsonwebtoken 사용)

import * as jwt from 'jsonwebtoken';
import * as fs from 'fs';

const APP_ID = process.env.GITHUB_APP_ID!;
const PRIVATE_KEY = fs.readFileSync('./private-key.pem', 'utf8');

const now = Math.floor(Date.now() / 1000);

const token = jwt.sign(
  {
    iat: now,
    exp: now + (10 * 60), // 10분 유효
    iss: APP_ID,
  },
  PRIVATE_KEY,
  { algorithm: 'RS256' }
);

📌 Installation Access Token 발급

import axios from 'axios';

const installationId = YOUR_INSTALLATION_ID;
const jwtToken = generateJwt();

const res = await axios.post(
  `https://api.github.com/app/installations/${installationId}/access_tokens`,
  {},
  {
    headers: {
      Authorization: `Bearer ${jwtToken}`,
      Accept: 'application/vnd.github+json',
    },
  }
);

const accessToken = res.data.token;

이 토큰을 이용하면 Webhook 서버에서 GitHub API를 안전하게 호출할 수 있습니다 🔐


4. GitHub App 기반 Webhook 처리 예시

🔹 Webhook 수신 엔드포인트 (/github/webhook)

import { Controller, Post, Headers, Req, Res } from '@nestjs/common';
import { verifySignature } from './utils/verifyAppSignature';

@Controller('github')
export class GithubController {
  @Post('webhook')
  async handleWebhook(
    @Headers('x-hub-signature-256') signature: string,
    @Req() req,
    @Res() res
  ) {
    const payload = JSON.stringify(req.body);

    if (!verifySignature(payload, signature)) {
      return res.status(401).send('Invalid signature');
    }

    const event = req.headers['x-github-event'];
    const action = req.body.action;

    // 이벤트 처리 로직
    console.log(`📥 GitHub App Event Received: ${event} - ${action}`);

    res.status(200).json({ received: true });
  }
}

🔐 Webhook 서명 검증 함수 (App Secret 사용)

import * as crypto from 'crypto';

export function verifySignature(payload: string, signature: string) {
  const secret = process.env.GITHUB_APP_WEBHOOK_SECRET!;
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(payload, 'utf-8');
  const expected = `sha256=${hmac.digest('hex')}`;
  return crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

5. 기존 Webhook 서버에서 App 기반 서버로 마이그레이션 하는 법

항목 기존 Webhook 방식 GitHub App 방식

인증 Secret만 검증 JWT + Installation Token 인증 추가
이벤트 수신 GitHub Webhook 설정 수동 관리 GitHub App 설치 시 자동 Webhook 연결
API 권한 PAT or OAuth Token 필요 App 토큰으로 안전하게 호출
리포지토리 연결 하나하나 설정 조직 전체 일괄 연결 가능

💡 마이그레이션은 점진적으로 가능합니다:
예: 기존 Webhook + App Webhook 병렬 운영 → 기능별로 점진적 전환


6. GitHub App의 활용 확장성 예시

  • 이슈 자동 분류 및 템플릿 기반 응답 생성
  • PR 생성 시 조건 분기 후 리뷰어/라벨 자동 지정
  • GitHub Marketplace 배포 → 다른 팀이 설치 가능
  • AI와 결합한 코멘트 자동 생성 (OpenAI + GitHub API)

7. 마무리 및 다음 글 예고

이번 글에서는 기존 Webhook 방식에서 GitHub App 기반 구조로 전환하는 이유, 방법, 그리고 실전 인증 로직까지 다뤘습니다.
다음 글에서는 "GitHub App 기반의 고급 자동화 기능 개발 (AI 응답, 이슈 분류, 멀티리포 지원 등)" 을 소개할 예정입니다! 🚀

 

 

※ 이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
글 보관함
반응형