Skip to content

logi Webhook Signature 검증 템플릿

logi 가 RP 에 보내는 webhook 의 X-Logi-Signature 헤더를 검증하는 drop-in 컨트롤러 템플릿 모음입니다. 외부 RP 개발자가 그대로 복붙해서 쓸 수 있도록 만들어졌습니다.

자세한 형식 spec 은 docs.1pass.dev/guide/webhook-verificationdocs.1pass.dev/guide/webhooks 참고.

왜 이 템플릿이 존재하나

가장 자주 빠뜨리는 step:

  1. Signature 검증 자체를 건너뛰기 (// TODO: verify) — 누가 webhook URL 만 알면 가짜 이벤트 주입 가능
  2. Timing-safe compare 미적용== 비교는 timing attack 으로 서명 추론 가능
  3. Raw body 가 아닌 파싱된 JSON 으로 HMAC 계산 — 공백/필드 순서가 달라 서명 영구 불일치
  4. Replay window 검증 누락 — 한 번 가로챈 webhook 이 영원히 재사용 가능
  5. Dual signature format 중 한쪽만 처리 — 새 이벤트 또는 legacy 이벤트 중 하나가 silent 401

이 템플릿들은 위 5개를 모두 박아둔 상태입니다.

Dual Signature Format

logi 는 두 가지 서명 형식이 공존 합니다. RP verifier 는 반드시 두 형식을 모두 받아들여야 합니다.

형식 ① Legacy (sha256=<hex>)

http
X-Logi-Event: user.deleted
X-Logi-Timestamp: 1735000000
X-Logi-Signature: sha256=a3d9f0...
  • 발송 이벤트: user.deleted, user.unlinked, consent.revoked, token.revoked
  • 서명: HMAC-SHA256(LOGI_WEBHOOK_SECRET, raw_body) → 16진수 hex
  • Timestamp 는 별도 헤더 X-Logi-Timestamp (UNIX seconds)

형식 ② PLAN-L canonical (t=,kid=,v1=)

http
X-Logi-Event: user.merged
X-Logi-Event-Id: 01HV...
X-Logi-Signature: t=1735000000,kid=whk_2025q4_a1,v1=a3d9f0...
  • 발송 이벤트: user.merged, user.grants_revoked, webhook_key.compromised 등 신규 이벤트
  • 서명: HMAC-SHA256(secret_for_kid, raw_body) → hex (v1= 필드)
  • Timestamp 는 서명 헤더 안 t= 필드
  • kid 는 회전 가능한 키 식별자 — 단일 키만 운영 중이면 무시하고 LOGI_WEBHOOK_SECRET 그대로 사용 가능

검증기는 헤더 값에 , 또는 t= 가 포함되면 PLAN-L, sha256= 로 시작하면 legacy 로 분기합니다.

공통 규약

항목
환경변수LOGI_WEBHOOK_SECRET (plaintext, rotate_webhook_secret API 응답에서 1회 노출)
Replay window5분 (300초) — timestamp diff 가 이를 초과하면 401
Bodyraw bytes — JSON 파싱 전 원본을 HMAC 입력으로 사용
Comparetiming-safe (Ruby ActiveSupport::SecurityUtils.secure_compare, Node crypto.timingSafeEqual 등)
실패 응답HTTP 401 — 절대 200 으로 silent fail 금지

템플릿 파일

  • rails.rb — Rails 8 (ApplicationController 상속)
  • express.ts — Express + TypeScript (express.raw 미들웨어)
  • nextjs-route.ts — Next.js 14+ App Router (route.ts handler)

각 파일 상단에 사용법 주석이 박혀 있습니다. 그대로 복사 후 LOGI_WEBHOOK_SECRET 환경변수만 주입하면 동작합니다. 템플릿 파일은 온보딩 과정에서 제공됩니다 — 요청은 support@1pass.dev 로 보내주세요.

이벤트별 dispatch

각 템플릿은 검증 통과 후 event_type 별로 분기하는 골격을 포함합니다. 처리 대상 이벤트는 docs.1pass.dev/guide/webhooks#이벤트-카탈로그 참고.

최종 수정:

Identity가 제품의 신뢰를 만듭니다.