API 키
세 종류의 자격증명, 세 가지 위협 모델.
pk_ — 공개 키
- 브라우저로 전달되도록 설계됨. 모든 서명된 B2B 요청에서
X-Client-ID헤더로 전송되며, 클라이언트 측 체크아웃 열기를 위해 SDK 번들에도 임베드됩니다. - 계정을 식별할 수 있지만, 세션을 생성하거나, 다른 가맹점의 데이터를 읽거나, 파괴적인 작업을 트리거할 수는 없습니다.
- 공개 키 유출은 저심각도 이벤트입니다.
sk_ — 시크릿 (HMAC 서명 키)
- 모든 B2B API 호출에 대한 HMAC-SHA256 서명 키 — 인증 참조.
- 절대 회선을 통해 전송되지 않습니다. 파생된 요청별 서명만 전송됩니다. 따라서 저장 레이어(env 변수, git, 로그)의 유출만 걱정하면 되며, 전송 레이어는 아닙니다.
- 서버 전용. 브라우저 번들, 공개 저장소, 스크린샷, 채팅 메시지에 절대 나타나면 안 됩니다.
- 시크릿 유출은 고심각도 이벤트입니다.
whsec_ — 웹훅 서명 시크릿
- 저희에서 가맹점 서버로의 인바운드 웹훅 전달의 서명을 검증하는 데 사용됩니다. 서명 검증 참조.
- 웹훅 엔드포인트별로 분리됨 — 등록된 엔드포인트 3개가 있으면 별개의
whsec_시크릿 3개를 가집니다. 환경은 프리픽스에 인코딩됩니다:whsec_live_…/whsec_test_…. - 서버 전용.
sk_와 마찬가지로 회선을 통해 전송되지 않습니다 — 로컬에서 HMAC을 검증하는 데만 사용됩니다. - 로테이션에 24시간 grace 윈도우가 있습니다. Rotate를 클릭하면 이전
시크릿이 새 시크릿과 함께 24시간 동안 수락된 상태로 유지됩니다(전달은
X-Signature와X-Signature-Prev를 모두 포함), 트래픽을 보류하지 않고 검증자를 재배포할 수 있습니다. - 기존 시크릿 노출은 새 2FA로 게이팅되고 감사 로그에 기록되어 사용할 수 있습니다 — 시크릿이 분실되었고 로테이션이 허용되지 않는 경우에 한합니다. 대시보드의 기본 자세는 “노출하지 말고 로테이션 하라”입니다.
- 유출된 웹훅 시크릿은 공격자가 가맹점 URL로 이벤트를 위조할 수 있게 합니다. 이벤트 페이로드를 얼마나 신뢰하는지에 따라 중간에서 고심각도입니다.
스코프
비밀 키는 스코프됩니다. 대시보드에서는 다음 스코프 번들 중 하나로 키를 발급할 수 있습니다.
| 스코프 | 가능한 작업 | 사용 사례 |
|---|---|---|
read | 주문, 세션, 환불, 잔액 목록/읽기 | 읽기 전용 통합(분석, BI) |
write_order | 모든 read + 세션 생성, 주문 생성, 주문 취소 | 스토어프론트 백엔드 |
write_refund | 모든 read + 환불 생성, 환불 실행 표시 | 고객 지원 도구 |
webhook_manage | 모든 read + 웹훅 엔드포인트 관리 | DevOps 도구 |
기본 발급 “전체 액세스” 키는 네 가지를 모두 가집니다. 용도별 키 발급은 여전히 좋은 위생입니다 — 의도를 문서화하고 강제가 도래할 때 준비하게 하지만 — 스코프를 보안 경계로 다루기 전에 아래 주의 사항을 읽으세요.
스코프는 현재 권고 사항이며 게이트웨이에서 강제되지 않습니다.
게이트웨이는 키의 HMAC 서명을 검증하고 가맹점 신원(X-Merchant-ID /
X-Merchant-Domain)을 다운스트림 서비스에 주입하지만, 키의 스코프를
전파하거나 검사하지 않습니다. 실질적으로 모든 스코프의 유출된
sk_가 가맹점의 모든 /b2b/v1/* 엔드포인트를 호출할 수 있습니다 —
read 키가 실제로 환불 생성을 막지 못합니다. 따라서 좁은 스코프는
아직 영향 범위를 제한하지 않습니다: 침해 계획에서 모든 비밀 키를
전체 액세스로 다루고, 빠른 로테이션 + 폐기(아래)를 실제 봉쇄 수단으로
의존하세요. 스코프별 강제는 로드맵에 있습니다.
로테이션
- 새 키 생성. 대시보드 → Developers → API keys → + Add key. 스코프를 선택. 대시보드는 시크릿을 한 번 표시합니다 — 즉시 저장하세요.
- 모든 환경에서 env 변수를 새 값으로 롤. 배포.
- 트래픽 확인. 대시보드는 키별 요청 카운트를 실시간으로 표시합니다. 이전 키의 카운트가 0으로 떨어질 때까지 기다리세요.
- 이전 키 폐기. 동일한 화면 → 케밥 메뉴 → Revoke.
현재 자동 오버랩 윈도우가 없습니다 — 키를 폐기하면 그것으로 서명된
진행 중인 요청은 401을 받습니다. 그에 따라 로테이션을 계획하세요:
먼저 새 키를 배포하고, 이전 키에서 트래픽을 빼낸 다음, 폐기하세요.
긴급 폐기
키가 유출된 경우(git 히스토리, 공개 번들, 로깅된 스택 트레이스, 파트너의 침투 테스트 보고서) — 일부 실패한 요청을 감수하더라도 즉시 폐기하세요. 공격자가 유효한 자격증명을 보유하게 하는 것보다 시끄럽게 실패하는 것이 낫습니다.
단계:
- 대시보드 → Developers → API keys → [key] → Revoke now. 효과는 즉시; grace 기간 없음.
- 대체 키 발급 및 배포.
- 최근 활동 감사 — 대시보드는 키별로 IP와 도달한 엔드포인트가 포함된 최근 30일간의 요청을 표시합니다.
침해가 키 하나보다 더 광범위하다고 의심되는 경우, [email protected]에 다음을 위해 문의하세요:
- 가맹점 계정에 대한 전체 감사 로그 내보내기
- 웹훅 시크릿 일괄 로테이션
- 조사하는 동안 선택적으로 계정 동결
저장 모범 사례
- Env 변수만. “REPLACE ME”라고 적힌
.env.example에서도 시크릿을 절대 git에 커밋하지 마세요. - 환경별 키. dev/staging/prod에 대해 다른
sk_test_…와sk_live_…, 시크릿 매니저(AWS Secrets Manager, Vault, Doppler 등)에서 소싱하세요. - Env 변수 액세스 제한. Kubernetes에서는
ConfigMap이 아닌Secret으로 마운트하세요. Vercel/Netlify에서는 프로젝트 전체 글로벌이 아닌 환경 변수 스코핑을 사용하세요. - 본문이 있는 요청을 로깅하지 마세요. 디버깅 중에도 —
X-Signature의 HMAC 서명은 일회용이지만 비즈니스 페이로드에는 PII가 포함될 수 있습니다.
현재 지원되지 않는 항목
- 비밀 키의 IP 허용 목록. 로드맵에 있음.
- OAuth 스타일의 스코프된 사용자별 토큰. 현재 키 모델은 가맹점별이며 사용자별이 아닙니다.
- 자동 키 로테이션(예: 플랫폼이 강제하는 주간 로테이션). 오늘은 수동입니다.
다음 단계
- 인증 — B2B 호출의 정확한 서명 알고리즘.
- 웹훅 → 서명 검증 —
whsec_이 인바운드 이벤트에서 어떻게 사용되는지.