logi Webhook Signature 검증 템플릿
logi 가 RP 에 보내는 webhook 의 X-Logi-Signature 헤더를 검증하는 drop-in 컨트롤러 템플릿 모음입니다. 외부 RP 개발자가 그대로 복붙해서 쓸 수 있도록 만들어졌습니다.
자세한 형식 spec 은 docs.1pass.dev/guide/webhook-verification 와 docs.1pass.dev/guide/webhooks 참고.
왜 이 템플릿이 존재하나
가장 자주 빠뜨리는 step:
- Signature 검증 자체를 건너뛰기 (
// TODO: verify) — 누가 webhook URL 만 알면 가짜 이벤트 주입 가능 - Timing-safe compare 미적용 —
==비교는 timing attack 으로 서명 추론 가능 - Raw body 가 아닌 파싱된 JSON 으로 HMAC 계산 — 공백/필드 순서가 달라 서명 영구 불일치
- Replay window 검증 누락 — 한 번 가로챈 webhook 이 영원히 재사용 가능
- 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 window | 5분 (300초) — timestamp diff 가 이를 초과하면 401 |
| Body | raw bytes — JSON 파싱 전 원본을 HMAC 입력으로 사용 |
| Compare | timing-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.tshandler)
각 파일 상단에 사용법 주석이 박혀 있습니다. 그대로 복사 후 LOGI_WEBHOOK_SECRET 환경변수만 주입하면 동작합니다. 템플릿 파일은 온보딩 과정에서 제공됩니다 — 요청은 support@1pass.dev 로 보내주세요.
이벤트별 dispatch
각 템플릿은 검증 통과 후 event_type 별로 분기하는 골격을 포함합니다. 처리 대상 이벤트는 docs.1pass.dev/guide/webhooks#이벤트-카탈로그 참고.