Webhook 알림
Webhook을 사용하면 Archyl 워크스페이스에서 변경이 발생할 때마다 실시간 HTTP POST 알림을 수신할 수 있습니다. Webhook을 생성하고, URL을 지정하고, 관심 있는 이벤트를 선택하면 해당 이벤트가 발생할 때마다 Archyl이 엔드포인트에 알림을 보냅니다.
개요
이벤트가 발생하면 — 시스템이 생성되거나, 릴리스가 배포되거나, ADR이 업데이트되면 — Archyl은 해당 이벤트를 구독하는 모든 Webhook에 HTTP POST 요청을 전송합니다. 엔드포인트는 무엇이 발생했는지, 누가 했는지, 어떤 프로젝트에 속하는지를 설명하는 JSON 페이로드를 수신합니다.
일반적인 사용 사례:
- Slack 또는 Teams 알림 — 아키텍처 변경 시 알림
- CI/CD 트리거 — 새 릴리스 생성 시 트리거
- 감사 로깅 — 외부 시스템으로 로그 전송
- 커스텀 대시보드 — 아키텍처 이벤트에 반응하는 대시보드
- 자동화 파이프라인 — 탐색 완료 시 실행
지원 이벤트
아키텍처 요소
| 카테고리 | 이벤트 |
|---|---|
| 시스템 | system.created, system.updated, system.deleted |
| 컨테이너 | container.created, container.updated, container.deleted |
| 컴포넌트 | component.created, component.updated, component.deleted |
| 코드 | code.created, code.updated, code.deleted |
| 관계 | relationship.created, relationship.updated, relationship.deleted |
| 오버레이 | overlay.created, overlay.updated, overlay.deleted |
프로젝트 관리
| 카테고리 | 이벤트 |
|---|---|
| 프로젝트 | project.created, project.updated, project.deleted |
| 릴리스 | release.created, release.updated, release.deployed |
| 요청 | request.created, request.merged, request.closed |
문서
| 카테고리 | 이벤트 |
|---|---|
| ADR | adr.created, adr.updated, adr.deleted |
| 문서 | documentation.created, documentation.updated, documentation.deleted |
| 플로우 | flow.created, flow.updated, flow.deleted |
| API 계약 | api_contract.created, api_contract.updated |
협업 및 분석
| 카테고리 | 이벤트 |
|---|---|
| 댓글 | comment.created |
| 화이트보드 | whiteboard.created |
| 이벤트 채널 | event_channel.created |
| 탐색 | discovery.completed |
| 인사이트 | insight.generated |
Webhook 생성
- 조직 설정으로 이동하여 Webhooks 탭을 선택합니다
- 새 Webhook을 클릭합니다
- 구성 정보를 입력합니다:
| 필드 | 필수 | 설명 |
|---|---|---|
| 이름 | 예 | 설명이 포함된 라벨 (예: "Slack — 아키텍처 변경") |
| URL | 예 | POST 요청을 수신할 HTTPS 엔드포인트 |
| 시크릿 토큰 | 아니오 | 페이로드 서명 검증에 사용되는 공유 시크릿 |
| 이벤트 | 예 | 이 Webhook을 트리거할 이벤트 선택 |
| 프로젝트 | 아니오 | 선택적으로 특정 프로젝트로 제한 |
- 생성을 클릭합니다
Webhook은 즉시 이벤트 수신을 시작합니다.
페이로드 형식
모든 Webhook 전달은 다음 구조의 JSON 페이로드를 전송합니다:
{
"event": "system.created",
"timestamp": "2026-03-10T14:30:00Z",
"data": {
"entityType": "system",
"entityName": "Payment Service",
"action": "created",
"userName": "vincent",
"projectId": "a1b2c3d4-...",
"projectName": "My Project"
}
}
| 필드 | 설명 |
|---|---|
event |
이벤트 유형 문자열 (예: container.updated, release.deployed) |
timestamp |
이벤트 발생 시각의 ISO 8601 타임스탬프 |
data.entityType |
변경된 엔티티의 유형 |
data.entityName |
영향받은 엔티티의 이름 |
data.action |
수행된 작업 |
data.userName |
이벤트를 트리거한 사용자 |
data.projectId |
이벤트가 발생한 프로젝트의 UUID |
data.projectName |
사람이 읽을 수 있는 프로젝트 이름 |
Content-Type 헤더는 항상 application/json입니다.
보안
요청 헤더
모든 Webhook 전달에는 다음 헤더가 포함됩니다:
| 헤더 | 예시 | 설명 |
|---|---|---|
Content-Type |
application/json |
항상 JSON입니다 |
User-Agent |
Archyl-Webhook/1.0 |
요청이 Archyl에서 전송되었음을 식별합니다 |
X-Archyl-Event |
system.created |
이 전달을 트리거한 이벤트 유형입니다 |
X-Archyl-Signature |
sha256=a1b2c3... |
HMAC-SHA256 서명입니다 (시크릿 토큰이 설정된 경우에만 포함) |
HMAC-SHA256 서명 검증
Webhook 생성 시 시크릿 토큰을 설정하면, Archyl은 HMAC-SHA256을 사용하여 모든 페이로드에 서명합니다. 서명은 X-Archyl-Signature 헤더에 다음 형식으로 전송됩니다:
sha256=<hex-encoded HMAC-SHA256 digest>
전달을 검증하려면:
- 원시 요청 본문을 읽습니다 (JSON 파싱 전의 정확한 바이트)
X-Archyl-Signature헤더를 읽고sha256=접두사를 제거하여 hex 서명을 추출합니다- 시크릿 토큰을 키로 사용하여 원시 본문의 HMAC-SHA256 해시를 계산합니다
- 결과를 hex 인코딩하고 2단계에서 추출한 서명과 상수 시간 비교를 수행합니다
- 일치하지 않으면 요청을 거부합니다
Go 예제:
func verifyArchylWebhook(r *http.Request, secret string) ([]byte, error) {
body, err := io.ReadAll(r.Body)
if err != nil {
return nil, err
}
header := r.Header.Get("X-Archyl-Signature")
if !strings.HasPrefix(header, "sha256=") {
return nil, fmt.Errorf("missing or invalid signature header")
}
signature := strings.TrimPrefix(header, "sha256=")
mac := hmac.New(sha256.New, []byte(secret))
mac.Write(body)
expected := hex.EncodeToString(mac.Sum(nil))
if !hmac.Equal([]byte(expected), []byte(signature)) {
return nil, fmt.Errorf("signature mismatch")
}
return body, nil
}
Node.js 예제:
const crypto = require("crypto");
function verifyArchylWebhook(req, secret) {
const header = req.headers["x-archyl-signature"] || "";
if (!header.startsWith("sha256=")) {
throw new Error("Missing or invalid signature header");
}
const signature = header.slice("sha256=".length);
const body = req.rawBody; // use raw body, not parsed JSON
const expected = crypto
.createHmac("sha256", secret)
.update(body)
.digest("hex");
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature))) {
throw new Error("Signature mismatch");
}
return JSON.parse(body);
}
Python 예제:
import hmac
import hashlib
def verify_archyl_webhook(body: bytes, header: str, secret: str) -> dict:
if not header.startswith("sha256="):
raise ValueError("Missing or invalid signature header")
signature = header.removeprefix("sha256=")
expected = hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, signature):
raise ValueError("Signature mismatch")
return json.loads(body)
타이밍 공격을 방지하기 위해 항상 상수 시간 비교(hmac.Equal, crypto.timingSafeEqual, hmac.compare_digest)를 사용합니다. 항상 원시 요청 본문을 기준으로 검증해야 합니다 — JSON을 파싱한 후 다시 직렬화하면 바이트 표현이 달라져 서명이 일치하지 않을 수 있습니다.
전달 이력
모든 Webhook은 최근 전달 기록을 유지합니다. 확인하려면:
- 조직 설정 > Webhooks로 이동합니다
- Webhook 이름을 클릭합니다
- 전달 탭을 엽니다
각 전달 항목에는 다음이 표시됩니다:
| 필드 | 설명 |
|---|---|
| 이벤트 | 전달을 트리거한 이벤트 유형 |
| 상태 코드 | 엔드포인트의 HTTP 응답 코드 |
| 타임스탬프 | 전달이 전송된 시각 |
| 소요 시간 | 요청에 걸린 시간 |
| 요청 페이로드 | 전송된 전체 JSON 본문 |
| 응답 본문 | 엔드포인트가 반환한 응답 |
전달 기록은 7일간 보존됩니다. 이후 자동으로 삭제됩니다.
녹색 배지는 성공적인 전달(2xx 응답)을 나타냅니다. 빨간색은 실패(2xx가 아닌 응답 또는 타임아웃)를 나타냅니다.
테스트
프로덕션에서 Webhook을 사용하기 전에 정상 작동을 확인하세요:
- Webhook 상세 페이지를 엽니다
- 테스트 전송을 클릭합니다
- Archyl이
event: "webhook.test"가 포함된 테스트 페이로드를 엔드포인트에 전송합니다 - 전달 탭에서 수신 여부를 확인하고 응답을 검사합니다
테스트 전달은 실제 이벤트와 동일한 서명 메커니즘을 사용하므로, 서명 검증 로직도 동시에 확인할 수 있습니다.
재시도 정책
전달이 실패하면(2xx가 아닌 응답 또는 네트워크 타임아웃) Archyl이 자동으로 재시도합니다:
| 시도 | 지연 시간 |
|---|---|
| 1차 재시도 | 1분 |
| 2차 재시도 | 5분 |
| 3차 재시도 | 30분 |
3회 재시도 실패 후 전달은 실패로 표시됩니다. 전달 탭에서 재시도를 클릭하여 실패한 전달을 수동으로 다시 트리거할 수 있습니다.
Webhook이 24시간 동안 지속적으로 실패하면, Archyl이 이를 비활성화하고 조직 관리자에게 알림을 보냅니다. 문제가 해결되면 Webhook 설정에서 다시 활성화하세요.
프로젝트별 필터링
기본적으로 Webhook은 조직 내 모든 프로젝트의 이벤트를 수신합니다. 범위를 좁히려면:
- Webhook을 편집합니다
- 프로젝트 항목에서 하나 이상의 프로젝트를 선택합니다
- 저장합니다
선택한 프로젝트에서 발생한 이벤트만 전달을 트리거합니다. 이는 서로 다른 팀이 서로 다른 프로젝트를 관리하며 자신의 작업에 대한 알림만 필요한 경우에 유용합니다.
Webhook을 다시 만들지 않고도 언제든지 프로젝트 필터를 업데이트할 수 있습니다.
모범 사례
빠르게 응답하기
엔드포인트는 10초 이내에 2xx 응답을 반환해야 합니다. 무거운 처리가 필요한 경우, Webhook을 즉시 수락하고 백그라운드 작업에서 비동기적으로 처리하세요.
서명 검증하기
항상 시크릿 토큰을 설정하고 X-Archyl-Signature 헤더를 검증하세요. 이를 통해 페이로드가 실제로 Archyl에서 전송되었으며 변조되지 않았음을 보장합니다.
HTTPS 사용하기
항상 HTTPS 엔드포인트를 사용하세요. Archyl은 일반 HTTP URL로 Webhook을 전달하지 않습니다.
프로젝트별 필터링하기
조직에 많은 프로젝트가 있는 경우, 관심 있는 프로젝트로 Webhook 범위를 제한하세요. 이렇게 하면 불필요한 노이즈와 처리를 줄일 수 있습니다.
중복 처리하기
드문 경우(네트워크 재시도, 인프라 장애 조치) 엔드포인트가 동일한 이벤트를 두 번 이상 수신할 수 있습니다. timestamp와 event 필드를 사용하여 중복을 감지하고 제거하세요.
전달 상태 모니터링하기
전달 탭을 주기적으로 확인하세요. 실패 패턴이 나타나면 엔드포인트 문제, 방화벽 규칙 또는 만료된 자격 증명을 의심할 수 있습니다.