Skip to content

RP 활성 헬스 체크 (RP Active Health Check)

1pass IdP 는 등록된 RP 들의 통합이 실제로 살아있는지 주기적으로 확인합니다. 트래픽 기반 시그널(첫 요청 대기 중 / 토큰 발급 통과)은 RP 가 미사용 상태인지 죽은 상태인지 구분할 수 없습니다. 활성 헬스 체크는 IdP 가 직접 RP 의 표준 엔드포인트를 호출해 응답을 검증함으로써 이 모호함을 제거합니다.

핵심

  • opt-in 방식: 신규 등록 RP 는 기본 활성, 기존 RP 는 개발자 콘솔에서 토글해 켭니다.
  • 매시간 1회 GET /.well-known/logi-rp-health.
  • HMAC-SHA256 서명 + client_id echo 검증 + 시계 드리프트 ±5분 검사.
  • 결과는 개발자 콘솔 카드 에 🟢 / 🟡 / 🔴 로 표시.

왜 필요한가

상황트래픽 기반 시그널활성 헬스 체크
방금 등록한 RP, redirect_uri 오타⏳ 첫 요청 대기 중 (구별 불가)🔴 즉시 감지
배포는 됐는데 OAuth 라우트가 빠짐⏳ 첫 요청 대기 중🔴 즉시 감지
RP cert 만료사용자 클릭 시점에 첫 발견🔴 1시간 안에 감지
실제로 잘 통합됨⏳ 첫 요청 대기 중 (사용자 없을 때)🟢 alive
RP 자체가 한가함 (예: 사이드 프로젝트)⏳ 첫 요청 대기 중 (영원히)🟢 alive (오해 없음)

프로토콜

요청

IdP 는 다음과 같이 RP 엔드포인트에 GET 요청을 보냅니다:

http
GET /.well-known/logi-rp-health HTTP/1.1
Host: example.com
User-Agent: logi-healthcheck/1.0
Accept: application/json
X-Logi-Timestamp: 1748345678
X-Logi-Client-Id: logi_xxxxxxxxxxxxxxxx
X-Logi-Signature: 7a91...64자 hex...
  • X-Logi-Timestamp: Unix epoch seconds (요청 생성 시각).
  • X-Logi-Client-Id: 검증 대상 client_id.
  • X-Logi-Signature: HMAC-SHA256(secret, "{timestamp}.{client_id}") 를 hex 인코딩.
  • secret: RP 가 앱 등록 직후 1회 노출 받은 LOGI_RP_HEALTH_SECRET (env 변수로 저장).

RP 측 검증

RP 핸들러는 응답하기 전에 반드시 다음 4가지를 검증해야 합니다:

1. X-Logi-Client-Id == 자신의 등록된 client_id      → 다르면 401
2. |now() - X-Logi-Timestamp|  ≤ 5분 (300초)        → 넘으면 401 (time_drift)
3. constant-time compare:
     hex(HMAC-SHA256(LOGI_RP_HEALTH_SECRET,
                     "{X-Logi-Timestamp}.{X-Logi-Client-Id}"))
     == X-Logi-Signature                             → 다르면 401 (hmac_invalid)
4. (선택) IP 화이트리스트 — 1pass IdP 의 outbound 대역만 허용

검증 통과 시 200 OK + JSON body:

json
{
  "status": "ok",
  "client_id": "logi_xxxxxxxxxxxxxxxx",
  "timestamp": "2026-05-27T12:34:56Z",
  "sdk_version": "logi-rp-integrate/1.0"
}
필드필수설명
status"ok" 또는 "degraded" (RP 가 의도적으로 부분 기능만 가용함을 알리고 싶을 때)
client_id반드시 echo. IdP 가 등록값과 strict-match 검증. RP host 가 정말로 이 client_id 와 매핑되었음을 증명.
timestampRP 서버 측 ISO 8601 시각. IdP 가 자신의 시각과 비교해 RP 측 시계 드리프트 감지 (>5분 이면 rp_time_drift_Ns 로 기록).
sdk_version(선택)로그 추적용

IdP 측 검증

IdP 는 응답을 다음 순서로 검증합니다:

  1. HTTP 200 (Net::HTTPSuccess) — 아니면 http_<code> 기록.
  2. body 가 JSON parseable — 아니면 body_not_json 기록.
  3. body.client_id == 등록된 client_id — 아니면 client_id_mismatch 기록.
  4. |now() - body.timestamp| ≤ 5분 — 아니면 rp_time_drift_Ns 기록.

모두 통과하면 rp_health_status: healthy 로 전이.

타이밍

  • 주기: 매시간 1회 (Render free tier RP 들의 keep-warm 부수효과).
  • 타임아웃: open 5초, read 15초 (Render free tier cold start 수용).
  • 재시도: 매 ping 당 1회만. 실패 시 다음 시간 ping 까지 기다림.
  • 트래픽: 시간당 RP 당 1 req. 11개 RP 기준 264 req/day.

상태 머신

상태의미전이 조건
unknown한 번도 핑된 적 없음 (신규 RP 또는 grandfathered)— (초기값)
healthy직전 핑 성공어느 상태든 1회 성공
degraded1~2회 연속 실패직전 healthy 였다가 1회 실패, 또는 unknown 에서 실패
unreachable3회 연속 실패연속 실패 카운터 ≥ 3
skipped모바일 전용 redirect_uri + health_url 미설정redirect_uri 가 deeplink scheme + override URL 없음

알림 정책

healthy → unreachable 전이에서만 운영자에게 push 알림이 발화합니다. unknown → unreachable 은 grandfathered RP 의 SDK 미적용 상태와 구별할 수 없으므로 알림 무음 — 핑 결과만 콘솔에 표시됩니다.

redirect_uri 가 com.example.app://oauth/callback 같은 커스텀 스킴이면 IdP 가 핑할 호스트가 없습니다. 두 가지 처리:

  1. Backend 가 있는 모바일 RP: 개발자 콘솔의 health endpoint URL 필드에 백엔드 호스트를 입력합니다 (예: https://api.example.com). IdP 는 항상 <health_url>/.well-known/logi-rp-health 를 호출합니다.
  2. Backend 가 없는 순수 모바일 RP: health_url 을 비우면 skipped 로 자동 마킹. 콘솔에 🔇 표시되고 핑 자체가 발생하지 않습니다.

시크릿 발급 + 회전

  • 신규 RP: 등록 직후 개발자 콘솔의 "client_secret 발급 완료" 페이지 에서 LOGI_RP_HEALTH_SECRET 도 함께 1회 노출됩니다.
  • 기존 RP (grandfathered): 개발자 콘솔에서 RP active health check 토글을 켜면 그 순간 시크릿이 신규 발급되고 다음 페이지에서 1회 노출됩니다.
  • 회전: 시크릿이 누출되거나 분실됐으면 콘솔의 rotate 버튼으로 즉시 재발급 (기존 시크릿은 즉시 무효화).

보안

  • LOGI_RP_HEALTH_SECRET 은 클라이언트 측 코드에 넣지 마세요. 모바일 앱 / SPA 번들에 포함되면 의미를 잃습니다.
  • 서버 측 환경 변수 (Render env / Vault / 1Password / AWS Secrets Manager 등) 에만 저장하세요.

통합 예시

스택별 drop-in 코드:

자가 진단

bash
# 자신의 RP 가 헬스 체크에 통과하는지 로컬에서 흉내내기:
TS=$(date +%s)
CID=logi_xxxxxxxxxxxxxxxx
SECRET=$LOGI_RP_HEALTH_SECRET
SIG=$(printf "%s.%s" "$TS" "$CID" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')

curl -i \
  -H "User-Agent: logi-healthcheck/1.0" \
  -H "X-Logi-Timestamp: $TS" \
  -H "X-Logi-Client-Id: $CID" \
  -H "X-Logi-Signature: $SIG" \
  "https://example.com/.well-known/logi-rp-health"
# 기대: 200 OK
# body.client_id == $CID

자주 묻는 질문

헬스 체크가 사용자 데이터에 접근하나요?

아니요. /.well-known/logi-rp-health공개 정적 엔드포인트 입니다. 응답은 client_id, status, timestamp 만 포함하며, 어떤 사용자 정보도 포함하지 않습니다. HMAC 서명은 RP 가 정말로 1pass 와 통합되어 있는지 증명하는 목적만 가집니다 — 트래픽 제한이나 인증 게이트가 아닙니다.

헬스 체크 실패가 자동으로 RP 를 정지시키나요?

아니요. unreachable 상태가 되어도 OAuth 흐름은 정상 동작합니다. 헬스 체크는 관측 도구 일 뿐 enforcement 가 아닙니다. 운영자가 콘솔을 보고 수동으로 판단합니다.

우리 서버 IP 를 1pass 에 알려야 하나요?

선택 사항. RP 측 핸들러가 outbound IP 화이트리스트로 추가 보안을 원할 경우 https://api.1pass.dev/.well-known/outbound-ips (publish 예정) 의 대역만 허용하면 됩니다. 그러나 HMAC 검증만으로도 충분히 안전합니다.

응답에 status: "degraded" 를 보내면 어떻게 되나요?

콘솔에 🟡 로 표시되지만 OAuth 흐름은 그대로 동작합니다. RP 가 "통합은 살아있지만 일부 부분 기능에 문제가 있음" 을 알리고 싶을 때 사용합니다.

모든 RP 가 헬스 엔드포인트를 구현해야 하나요?

신규 등록 RP 는 권장됩니다. 콘솔에서 health_check_enabled 토글을 꺼두면 핑 자체를 받지 않습니다. 모바일 전용 RP 처럼 백엔드 자체가 없는 케이스는 자동으로 skipped 처리됩니다.

관련 문서

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