Skip to content

ADR 0003 HMAC Signed Callback

SANGMIN PARK edited this page Jul 17, 2026 · 1 revision

ADR-0003. 내부 콜백을 HMAC으로 서명

  • 상태: Accepted
  • 결정일: 2026-03-14
  • 마지막 검증: 2026-07-18

맥락

스크래핑 Worker의 결과 콜백은 API Gateway를 통해 Backend의 내부 엔드포인트로 전달됩니다. 네트워크 접근 제한이나 고정 Bearer Token만으로는 요청 본문 변조 여부와 재전송된 오래된 요청을 함께 검증하기 어렵습니다.

서명 검증 전에 JSON을 파싱하거나 다시 직렬화하면 공백과 필드 순서 차이로 Worker와 Backend의 서명 대상이 달라질 수 있습니다.

결정

  1. Worker와 Backend는 환경별 SCRAPING_CALLBACK_HMAC_SECRET을 공유합니다.
  2. Worker는 timestamp + "." + rawBody를 HMAC-SHA256으로 서명합니다.
  3. X-TimestampX-Signature는 필수이며 Backend는 JSON 파싱 전에 수신한 raw body로 검증합니다.
  4. Backend는 기본 300초의 timestamp 허용 범위를 적용해 오래된 요청을 거부합니다.
  5. 실제 서명과 기대 서명은 상수 시간 비교를 사용합니다.
  6. 서명이 유효한 요청만 콜백 DTO 검증과 Job 상태 처리로 진행합니다.

검토한 대안

네트워크 접근 제한만 사용

내부 네트워크 구성 오류나 우회 경로가 생기면 요청 자체의 발신자와 무결성을 확인할 수 없습니다. 네트워크 제한은 보조 통제로 사용하고 애플리케이션 서명을 유지합니다.

고정 Bearer Token만 사용

발신자 인증은 가능하지만 Token이 노출되면 임의의 body를 만들 수 있고 요청 시각도 검증하지 못합니다.

파싱한 JSON을 정규화해 서명

양쪽 구현이 같은 canonicalization 규칙을 완전히 공유해야 합니다. 현재 계약은 전송된 원문을 그대로 서명해 규칙을 단순하게 유지합니다.

결과

장점

  • 콜백 본문의 무결성과 공유 Secret 보유 여부를 함께 확인합니다.
  • timestamp 허용 범위 밖의 재전송 요청을 차단합니다.
  • JSON 직렬화 방식과 무관하게 전송된 원문을 기준으로 검증합니다.

비용과 제약

  • Worker와 Backend의 Secret, 서버 시간, canonical 문자열 규칙이 정확히 같아야 합니다.
  • Secret 교체 시 두 시스템의 배포 순서와 호환 구간을 관리해야 합니다.
  • HMAC은 발신 시스템의 신원 분리나 Secret 유출 후 부인 방지를 제공하지 않습니다.

운영 규칙

  • Secret 값과 실제 서명을 로그, Wiki, Issue에 기록하지 않습니다.
  • 서명 오류는 timestamp 차이, signature encoding, body hash만으로 진단합니다.
  • Proxy나 Middleware가 서명 계산 후 body를 변경하지 않는지 확인합니다.
  • 계약 변경은 HmacSignatureVerifierUnitTests로 검증합니다.

재검토 조건

  • Worker별 독립 키와 안전한 자동 교체가 필요합니다.
  • API Gateway mTLS 또는 검증 가능한 Workload Identity를 도입합니다.
  • 300초 허용 범위가 실제 Queue 지연이나 보안 목표를 충족하지 못합니다.

근거

Clone this wiki locally