Webhook 연동
logi 는 RP 에 다음 이벤트를 통지합니다.
이벤트 카탈로그
| event_type | 발송 경로 | 언제 |
|---|---|---|
user.deleted | legacy | 사용자 계정 삭제 |
user.unlinked | legacy | 제휴사 앱 연결 해제 |
consent.revoked | legacy | scope 동의 철회 |
token.revoked | legacy | Access/Refresh Token 강제 무효화 |
user.merged | PLAN-L outbox | 두 logi 계정이 통합됨 — 자세한 페이로드는 Account Merge + Merge Idempotency 참고 |
user.grants_revoked | PLAN-L outbox | 사용자가 RP 에 부여한 모든 grant 일괄 철회 |
webhook_key.compromised | PLAN-L outbox | 운영자가 webhook signing key 를 강제 폐기 (RP 즉시 회전 필요) |
발송 경로 가 PLAN-L 인 이벤트는 신 형식 서명 (t=,kid=,v1=) 으로만 도착하고, legacy 이벤트는 당분간 구 형식 (sha256=) 으로 도착합니다. 자세한 형식 분기는 아래 참조.
설정
앱 등록 시 webhook_url 지정. 변경은 PATCH /api/v1/applications/:id.
🛡️ URL 정책 (P1 SSRF 방어)
https://만 허용 (개발 환경에서는http://localhost,http://127.0.0.1예외)- 등록·디스패치 시점 모두 호스트를 DNS resolve 후 검증:
- 사설 IP 대역 차단 (10/8, 172.16/12, 192.168/16, 127/8, 169.254/16, 100.64/10)
- 링크-로컬 / 멀티캐스트 차단
- IPv6 사설/루프백/링크-로컬도 동일 차단
- DNS rebinding 방어: 검증된 IP로 직접 connect하고, SNI/Host 헤더는 원본 도메인 유지
- 위반 시 해당 이벤트는
ssrf_blocked사유로 발송 실패 처리
시크릿 회전
webhook signing secret은 반드시 회전해주세요. 회전 전까지는 BCrypt fallback으로 서명되며, 이 경우 응답 헤더에 X-Logi-Secret-Deprecated: true와 Deprecation 헤더가 포함됩니다 — 개발자 포털에서 회전을 권장합니다.
curl -X POST -H "Authorization: Bearer $PAK" \
https://api.1pass.dev/api/v1/applications/:id/rotate_webhook_secret회전 응답 시 plaintext가 1회만 노출됩니다. 이후 검증에 사용하세요.
만료 정책
- 기본 TTL: 1년
- 만료 30일 전부터 admin/developer에게 알림 (감사 로그 + Phase 2에서 이메일)
- 만료된 client_secret으로 토큰 발급 시도 시
invalid_client거부
요청 형식 — 두 가지 서명 포맷이 공존합니다
logi 는 현재 두 가지 서명 형식을 동시에 사용 합니다. RP 의 verifier 는 반드시 두 형식 모두 받아들여야 합니다.
① PLAN-L outbox (canonical, 신규 이벤트는 이 경로)
Logi::Webhooks::DeliveryJob 이 발송. user.merged, user.grants_revoked, webhook_key.compromised 등 PLAN-L 이후 이벤트는 모두 이 경로.
POST https://your.app/hooks/logi
Content-Type: application/json
X-Logi-Event: user.merged
X-Logi-Event-Id: 01HV... # idempotency 키 (`event_id`)
X-Logi-Delivery-Id: 12345 # 재시도마다 동일
X-Logi-Signature: t=1735000000,kid=whk_2025q4_a1,v1=a3d9f0...
{"event_id":"01HV...","event_type":"user.merged","data":{...},"created_at":"..."}서명은 HMAC-SHA256(secret_for_kid, raw_body) — kid 로 키를 lookup 한 뒤 검증.
② Legacy WebhookDispatchJob (deprecated, back-compat)
기존 4개 이벤트 (user.deleted, user.unlinked, consent.revoked, token.revoked) 가 아직 이 경로로 발송됩니다.
POST https://your.app/hooks/logi
Content-Type: application/json
X-Logi-Event: user.deleted
X-Logi-Delivery-Id: 12345
X-Logi-Timestamp: 1735000000
X-Logi-Signature: sha256=a3d9f0...
{"id":12345,"event_type":"user.deleted","payload":{"user_id":42},"created_at":"..."}서명은 HMAC-SHA256(webhook_secret, raw_body) — 단일 secret.
검증기 작성 가이드: HMAC 서명 검증 페이지에 두 형식을 모두 처리하는 verifier 예시가 있습니다 — 헤더 값에 , 가 포함되면 PLAN-L 형식, sha256= 로 시작하면 legacy 로 분기합니다.
재시도 정책
Legacy 경로
- 최대 10회 (24h 내)
- 지수 백오프: 1m → 2m → 4m → 8m → 16m → 32m → 60m → 120m → 240m → 480m
- 2xx 응답이면 전달 완료. 3xx/4xx/5xx 및 타임아웃은 재시도
- 10회 모두 실패 →
failed_at마킹 · 개발자 포털에 표시
PLAN-L outbox 경로
- 최대 5회 — Linear-style 백오프: 1m → 5m → 30m → 2h → 6h
- 2xx → 전달 완료
- 408 / 429 / 5xx → 재시도
- 그 외 4xx → 즉시 DLQ (RP 가 명시적으로 거부한 것으로 해석)
- 5회 모두 실패 → DLQ → 개발자 포털 +
webhook_outbox_entries.dlq_at마킹