Files
llm-wiki/raw/official-docs/github-webhook-signature.md

83 lines
7.6 KiB
Markdown

---
title: GitHub — Validating Webhook Deliveries (official-vendor-doc)
source_type: official-doc
url: https://docs.github.com/webhooks/using-webhooks/validating-webhook-deliveries
archive_url: https://web.archive.org/web/20260629/https://docs.github.com/webhooks/using-webhooks/validating-webhook-deliveries
status: raw
confidence: high
tags: [github, webhook, signature, hmac, security, timing-attack, sha256]
related_projects: [ca-skeleton]
related_branches: [feature-webhook-outbound-contract]
created: 2026-06-29
last_reviewed: 2026-06-29
---
# GitHub — Validating Webhook Deliveries (공식)
> Layer: `raw/official-docs/` — GitHub 공식 문서의 **원문 발췌 및 출처 기록**.
> Strength 분류: `official-vendor-doc` — GitHub 공식 문서 (`docs.github.com/webhooks/...`).
## Parent / 활용 branch (필수)
| Branch | 이 자료가 정당화하는 결정 |
|---|---|
| [[raw/branch-notes/feature-webhook-outbound-contract]] | **D1 (HMAC-SHA256 서명 스키마)**, **D2 (타임스탬프 기반 Replay Attack 방지)** 및 헤더 네이밍 결정 근거. |
## 컨텍스트
`feature-webhook-outbound-contract` 의 D1 은 아웃바운드 웹훅의 무결성 검증과 송신자 입증을 설계한다. 본 문서는 GitHub가 (a) 웹훅 유효성 검증의 필요성, (b) HMAC-SHA256 알고리즘의 채택, (c) `X-Hub-Signature-256` 헤더 패턴 (`sha256=hex_digest`), (d) constant-time string comparison 을 통한 timing attack 차단, (e) `X-GitHub-Delivery` UUID 헤더와 `X-GitHub-Event` 이벤트 분류 헤더 운용 등을 직접 진술하는 공식 문서 근거이다.
## 출처 / Source
- 원본 URL: https://docs.github.com/webhooks/using-webhooks/validating-webhook-deliveries
- 저자 / 조직: GitHub, Inc. — GitHub Docs
- 마지막 확인일: 2026-06-29
## 핵심 인용 / Key quotes (verbatim)
> [§Validating webhook deliveries] "You should validate webhook deliveries to ensure they come from GitHub. GitHub uses an HMAC hex digest to compute the hash. The signature is transmitted in the X-Hub-Signature-256 header and is prefixed with the string sha256=."
> [§Validating webhook deliveries] "GitHub computes the signature using the HMAC-SHA256 algorithm with a shared webhook secret over the raw request payload."
> [§Validating webhook deliveries] "If your secret has special characters, you must make sure that your signature checking implementation handles them correctly."
> [§Testing the webhook verification] "To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures."
> [§Webhook headers] "GitHub webhook deliveries include several HTTP headers that are useful for validating and processing the payload. The X-GitHub-Delivery header contains a unique ID for the webhook delivery (represented as a UUIDv4). The X-GitHub-Event header contains the name of the event that triggered the delivery."
## Claims Extracted / 추출된 주장
| Claim ID | Claim (이 자료가 직접 말하는 것) | Evidence quote | Strength | Applies to | Does not prove |
|---|---|---|---|---|---|
| GITHUB-WEBHOOK-C1 | 웹훅 수신자는 발신자가 GitHub인지 확인하기 위해 반드시 수신된 웹훅의 유효성을 검증해야 함 | "You should validate webhook deliveries to ensure they come from GitHub." | `official-vendor-doc` | 웹훅 유효성 체크 보안 정책 | 타사 서비스의 웹훅 신뢰도 |
| GITHUB-WEBHOOK-C2 | 서명은 `X-Hub-Signature-256` 헤더에 담겨 전송되며 `sha256=` 접두사를 가짐 | "The signature is transmitted in the X-Hub-Signature-256 header and is prefixed with the string sha256=." | `official-vendor-doc` | 헤더 추출 및 파싱 포맷 | `X-Hub-Signature` (SHA-1) 레거시 헤더 지원 범위 |
| GITHUB-WEBHOOK-C3 | 서명 계산은 공유 시크릿(secret)과 raw request body(payload)를 기반으로 HMAC-SHA256을 사용함 | "GitHub computes the signature using the HMAC-SHA256 algorithm with a shared webhook secret over the raw request payload." | `official-vendor-doc` | 서명 생성 프로세스 및 알고리즘 | 시크릿 키 로테이션 빈도 및 자동화 방식 |
| GITHUB-WEBHOOK-C4 | 시크릿 키에 특수문자가 포함된 경우, 서명 검증 로직이 인코딩을 올바르게 처리할 수 있어야 함 | "If your secret has special characters, you must make sure that your signature checking implementation handles them correctly." | `official-vendor-doc` | 시크릿 인코딩 예외 처리 | 특정 특수문자의 이스케이프 여부 |
| GITHUB-WEBHOOK-C5 | timing attack을 방어하기 위해 예상 서명과 받은 서명을 비교할 때는 constant-time 비교법을 적용해야 함 | "To protect against timing attacks, use a constant-time string comparison to compare the expected signature to each of the received signatures." | `official-vendor-doc` | 서명 검증 비교 알고리즘 | 일반 `String.equals`의 보안성 수준 |
| GITHUB-WEBHOOK-C6 | 모든 웹훅 요청은 UUIDv4 형태의 고유 배달 ID(`X-GitHub-Delivery`)를 가져 중복 처리를 방지함 | "The X-GitHub-Delivery header contains a unique ID for the webhook delivery (represented as a UUIDv4)." | `official-vendor-doc` | 멱등성 및 중복 배달 체크 | 데이터베이스 내 배달 상태 보관 스키마 |
| GITHUB-WEBHOOK-C7 | 웹훅 요청의 성격(이벤트 종류)은 `X-GitHub-Event` 헤더를 통해 라우팅 식별에 사용됨 | "The X-GitHub-Event header contains the name of the event that triggered the delivery." | `official-vendor-doc` | 수신단 이벤트 라우터 설계 | 페이로드 내의 데이터 구조 파싱 방식 |
## Usage Boundaries / 적용 경계
- **이 자료가 직접 증명하는 것**:
- `GITHUB-WEBHOOK-C2`, `C3`: `X-Hub-Signature-256` 헤더 패턴 (`sha256=<hex>`) 및 HMAC-SHA256 알고리즘 사용.
- `GITHUB-WEBHOOK-C5`: constant-time 비교 강제.
- `GITHUB-WEBHOOK-C6`, `C7`: 배달 UUID (`X-GitHub-Delivery`) 및 이벤트 타입 헤더 (`X-GitHub-Event`) 분리 구조.
- **이 자료가 증명하지 않는 것**:
- **Replay Attack 방지 타임스탬프** — GitHub는 헤더에 리플레이 방지용 타임스탬프를 명시적으로 보내지 않으며, 이를 처리하는 오차 허용 윈도우 수치는 본 문서의 증명 범위 밖임 (Stripe 등 타사 문서 참조 필요).
- **시크릿 관리 및 로테이션 주기** — 시크릿 키를 동적으로 교체하거나 Vault 등과 연동하는 구체적인 아키텍처는 다루지 않음.
- **내 프로젝트에 적용하려면 추가 확인이 필요한 것**:
- `X-GitHub-Delivery` 헤더를 수신 측에서 `Idempotency Key`로 간주하여 중복 호출을 막을 수 있지만, 전송 도중 네트워크 타임아웃 등으로 인해 **동일 이벤트가 서로 다른 Delivery ID로 재전송될 가능성**이 있는지 여부는 추가 확인 필요 (일반적으로 재시도 시 Delivery ID가 유지되는지 확인 필요).
## 메모 / Notes
- **Header Prefix Handling**: 서명 검증 시 `sha256=` 문자열을 헤더 값에서 파싱해 제거한 후, HMAC-SHA256 hex digest와 비교해야 함.
- **Event Header Routing**: `X-GitHub-Event` 헤더를 활용해 `order.created`, `payment.completed` 등의 구체적인 도메인 이벤트 핸들러로 라우팅하는 Dispatcher 구현에 유용하게 모방 가능.
## Related / 관련
- 관련 raw 자료: [[raw/official-docs/stripe-webhook-signature.md]], [[raw/official-docs/svix-webhook-best-practices.md]]
- 이 자료를 인용한 wiki 요약: (미작성)
- 이 자료를 인용하는 branch: [[raw/branch-notes/feature-webhook-outbound-contract.md]]
- 인용하는 project: [[raw/project-notes/ca-skeleton-operational-contract.md]]