Skip to Content

인증

InfraIO Pay에는 인증 모델이 다른 두 가지 API 표면이 있습니다. 호출자가 누구인지에 맞는 것을 선택하세요.

표면경로 프리픽스대상인증
가맹점 B2B/b2b/v1/*가맹점 서버HMAC-SHA256 요청 서명
대시보드서비스별: /auth/*, /payment/*, /merchant/*, /event/*, /user/*, …가맹점 대시보드 브라우저 세션Bearer JWT

이 페이지는 B2B 표면을 다룹니다 — API 키 쌍으로 가맹점 서버에서 호출하는 표면입니다. InfraIO 대시보드를 임베드하거나 내부 도구를 만드는 경우 대시보드 표면을 사용하세요(별도 문서, 아직 공개되지 않음).

게이트웨이는 각 표면을 선행 프리픽스로 라우팅한 후 제거하여 전달합니다. /b2b/v1/checkout-sessions/quick은 payment-service에 /v1/checkout-sessions/quick 으로 도달하고, 대시보드의 /payment/v1/orders/v1/orders로 도달합니다. 따라서 다른 곳에서 /v1/* 베어 경로를 본다면, 그것은 공개 프리픽스가 제거된 후의 백엔드 내부 경로입니다 — 클라이언트는 항상 프리픽스가 붙은 형식을 보냅니다. (서명에 대한 한 가지 결과: B2B 정규 문자열은 /b2b 프리픽스가 그대로 붙은 경로를 서명합니다 — 아래 참조.)

엔드포인트

환경기본 URL
테스트https://api-dev.infraio.xyz
라이브https://api.infraio.xyz

동일한 URL 패턴 — 환경은 URL이 아닌 키 프리픽스(pk_test_… vs pk_live_…)로 제어됩니다.

키 쌍

가맹점 대시보드(Developers → API keys → + Add key)에서 두 가지 값을 받습니다.

  • 공개 키(pk_test_… 또는 pk_live_…) — 계정을 식별합니다. X-Client-ID로 전송됩니다. 브라우저 번들에 임베드해도 안전합니다(SDK가 이미 그렇게 합니다).
  • 비밀 키(sk_test_… 또는 sk_live_…) — HMAC 서명 키. 서버 전용입니다. 데이터베이스 패스워드처럼 다루세요.

비밀 키가 브라우저 번들, git 저장소, 로그 라인, 또는 공유 채팅에 노출된 경우 — 대시보드에서 즉시 폐기하세요. 오버랩 윈도우는 없습니다. 폐기는 즉시 적용됩니다. 새 키를 발급하고 재배포하세요.

요청 서명

/b2b/v1/*에 대한 모든 호출은 세 개의 헤더를 포함합니다.

X-Client-ID: pk_live_70d0becbd7a53047b0dfe88a960d10ad X-Timestamp: 1715990400 X-Signature: 9a8b7c6d… (hex HMAC-SHA256)

서명은 정규 문자열에 대해 계산됩니다.

METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODY
  • METHOD — 대문자 HTTP 동사(POST, GET, …).
  • PATH — 호스트 없이, 쿼리 문자열 없이 /b2b 프리픽스가 포함된 요청 경로(예: /b2b/v1/checkout-sessions/quick). 게이트웨이는 /b2b를 제거하기 전에 원본 인바운드 경로에 대해 서명을 검증하므로 프리픽스가 반드시 있어야 합니다. 쿼리 매개변수는 서명되지 않습니다GET …?cursor=…&limit=20의 경우, ?… 부분이 아닌 경로만 서명하세요.
  • TIMESTAMP — 10진수 문자열로 된 유닉스 초(예: "1715990400"), X-Timestamp와 정확히 일치해야 함.
  • BODY — 원본 요청 본문 바이트. GET/DELETE의 경우 빈 문자열.

비밀 키로 HMAC-SHA256 서명, hex로 출력:

import { createHmac } from "node:crypto"; function sign({ method, path, body, secret }: { method: string; path: string; body: string; secret: string; }) { const timestamp = Math.floor(Date.now() / 1000).toString(); const input = [method.toUpperCase(), path, timestamp, body].join("\n"); const signature = createHmac("sha256", secret).update(input).digest("hex"); return { timestamp, signature }; }

왜 HMAC이고 Bearer가 아닌가?

베어 Bearer 토큰 API는 모든 요청에서 유일한 시크릿을 회선을 통해 전송합니다. TLS-종료 프록시 로그 하나를 캡처한 누구나 계정 키를 얻게 됩니다. HMAC 서명은 시크릿이 절대 전송되지 않음을 의미합니다 — 일회용인 파생 서명(해당 정확한 요청 + 해당 정확한 분에 바인딩됨)만 전송됩니다.

트레이드오프: 모든 호출에 대해 서명을 계산해야 합니다. 서버 SDK가 이를 숨기겠지만, 공개될 때까지 위의 헬퍼는 언어당 약 15줄입니다.

타임스탬프 허용 오차

바인딩 허용 오차는 ±5분(300초)이며, 서명을 검증할 때 merchant-service가 강제합니다. 게이트웨이 자체는 방어 차원에서 약간 더 느슨하지만(310초), 게이트웨이를 통과하고 내부 검증에서 실패하는 요청은 여전히 401 invalid_signature로 끝납니다 — 계약상 300초로 가정하세요. 두 가지 시사점:

  1. NTP로 서버 클록을 동기화하세요. 드리프트된 클록을 가진 장시간 실행 크론은 간헐적으로 실패합니다.
  2. 서명을 미리 계산하여 큐에 넣지 마세요. 요청이 재시도 큐에 5분 이상 머무르면 서명이 만료됩니다.

키 스코프

비밀 키는 다음 스코프 번들 중 하나 이상을 가집니다.

스코프의도된 사용
read주문, 세션, 환불 목록/읽기
write_order체크아웃 세션, 주문 생성
write_refund환불 발행, 환불 요청 토큰 발급
webhook_manage웹훅 엔드포인트 생성/업데이트/삭제

대시보드는 기본적으로 “전체 액세스” 키(네 가지 스코프 모두)를 발급합니다. Developers → API keys → + Add key에서 통합이 필요한 스코프만 체크하여 제한된 스코프 키를 발급할 수 있습니다.

현재 스코프 강제는 권고 사항이며 게이팅되지 않습니다. 스코프는 키에 기록되고 대시보드에 표시되지만, 게이트웨이 미들웨어는 아직 범위 밖의 호출을 거부하지 않습니다 — 모든 유효한 sk_… 키는 오늘 전체 액세스로 동작합니다. 엔드포인트별 스코프 게이팅은 다음 릴리스에 있습니다. 아직 스코프를 보안 경계로 의존하지 마세요 — 그동안은 라벨로 다루고 키를 로테이션/폐기하여 액세스를 제한하세요.

서명이 검증되는 곳

HMAC 검증은 게이트웨이에서 한 번 발생합니다. 게이트웨이는:

  1. X-Client-ID, X-Timestamp, X-Signature를 읽습니다.
  2. pk_…로 가맹점 + 시크릿을 조회하고, 타임스탬프 윈도우 검사를 실행하고, 서명을 재계산하고, 상수 시간 비교를 수행합니다.
  3. 성공 시 인증 헤더를 제거하고 내부 헤더를 요청에 스탬프(X-B2B-Auth: 1, X-Merchant-ID, X-Merchant-Domain)하여 다운스트림 서비스(payment-service, merchant-service 등)로 전달합니다. 환경 + 해결된 스코프는 현재 주입되지 않습니다 — 환경이 필요한 다운스트림 코드는 헤더가 아닌 요청 본문/가맹점별 구성에서 도출합니다.
  4. 실패 시 백엔드를 건드리지 않고 **401 INVALID_SIGNATURE**를 반환합니다.

다운스트림 서비스는 HMAC을 재실행하지 않습니다 — 게이트웨이의 주입된 헤더를 신뢰하고 게이트웨이가 해결한 가맹점에 대해 동작합니다. 엔드포인트별 스코프 게이팅도 하지 않습니다: 위에서 언급한 대로 키의 스코프가 주입되지 않으므로, 인증된 sk_…는 가맹점의 모든 엔드포인트에 도달합니다 (스코프 강제는 현재 권고 사항입니다 — 키 스코프 아래의 콜아웃 참조). 이는 두 가지 방식으로 중요합니다.

  • InfraIO Pay 앞에 자체 리버스 프록시를 운영하는 경우, X-B2B-Auth / X-Merchant-ID를 제거하지 마세요(그리고 위조하지도 마세요 — 게이트웨이는 공개 엣지에서 이를 포함한 인바운드 요청을 거부합니다).
  • 공개 네트워크 경로(/b2b/v1/*)는 HMAC 단계를 실행하는 유일한 표면입니다. 서비스 간 내부 gRPC는 mTLS를 사용합니다 — X-Client-ID를 받지 않는 다른 신뢰 모델입니다.

다음 단계

  • 오류 — 4xx/5xx 응답 형식.
  • 보안 → API 키 — 로테이션, 폐기, 시크릿 유출 시 조치.
  • 웹훅 → 서명 검증다른 HMAC 방식을 사용합니다(헤더 X-Signature: sha256=…, X-Timestamp + "." + raw_body 서명, 24시간 로테이션 grace 윈도우 동안 선택적 X-Signature-Prev). 방식을 혼동하지 마세요 — 해시 알고리즘은 같지만 서명된 바이트와 시크릿 패밀리(whsec_… vs sk_…)가 다릅니다.