고객 데이터를 저장하지 않습니다 — 계좌정보 무저장 원칙

목차

1. 우리가 계좌정보를 저장했던 이유

이전까지 Bank API는 조회를 하기 전에 계좌를 먼저 등록하도록 요구했습니다. 등록 시 계좌번호는 원문 그대로가 아니라 SHA-256 단방향 해시로 변환되어 저장되었고, 조회 요청이 들어오면 이 해시와 대조해 등록된 계좌만 조회할 수 있게 했습니다.

이렇게 한 이유는 두 가지였습니다.

  • 무분별한 조회 방지 — 아무 계좌번호나 넣어 마구 조회하는 것을 막기 위해서였습니다.
  • 사용 계좌의 명시적 관리 — API Key별로 어떤 계좌를 쓰는지 스스로 통제할 수 있도록 하기 위해서였습니다.

중요한 점은, 저장한 값이 계좌번호 원문이 아니라 복호화가 불가능한 해시였다는 것입니다. 해시값만으로는 원래 계좌번호를 되돌릴 수 없습니다. 그럼에도 불구하고 "계좌와 관련된 어떤 파생 데이터라도 우리 서버(DB)에 남아 있다"는 사실 자체를, 우리는 계속 마음에 걸려 했습니다.

2. 이번 고도화: 이제 저장하지 않습니다

이번 업데이트로 계좌 등록 절차를 완전히 없앴습니다. 이제는 계좌번호를 해시로도 저장하지 않습니다.

핵심: 조회 요청에 담겨 온 계좌번호·비밀번호·생년월일은 은행 조회에만 사용된 뒤 즉시 폐기됩니다. 데이터베이스(Firestore)에는 계좌와 관련된 그 어떤 값도 — 원문은 물론 해시조차 — 남지 않습니다.

사용 방법도 더 간단해졌습니다. 별도의 등록 단계 없이, 올바른 요청만 보내면 바로 조회됩니다.

등록 없이 바로 조회
curl -X POST https://api.bankapi.co.kr/v1/transactions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer {apiKey}:{secretKey}" \
  -d '{
    "bankCode": "NH",
    "accountNumber": "계좌번호",
    "accountPassword": "****",
    "residentNumber": "YYMMDD",
    "startDate": "20260101",
    "endDate": "20260112"
  }'

우리 데이터베이스는 이제 최소한의 이용자 정보(이메일 등)와 API 키만 관리합니다. 고객이 입력하는 계좌 관련 값은 그 어떤 것도 저장하지 않습니다.

3. "해시 저장"과 "무저장"의 차이

"어차피 복호화가 안 되는 해시였는데 무슨 차이냐"고 물으실 수 있습니다. 차이는 분명합니다.

구분 이전 (해시 저장) 현재 (무저장)
DB에 남는 것 계좌 해시값(SHA-256) 없음
원문 복원 불가능 불가능 (애초에 저장 자체가 없음)
유출 시 노출 범위 해시값 (원문은 아니지만 존재) 노출될 데이터 자체가 없음

해시는 안전한 저장 방식이지만, 결국 "저장은 한다"는 전제 위에 있습니다. 가장 확실한 보호는 애초에 저장하지 않는 것입니다. 남기지 않은 데이터는 유출될 수도, 오용될 수도 없습니다.

4. 그럼 무분별한 조회는 어떻게 막나요?

계좌 등록이 사라졌다고 해서 남용을 방치하는 것은 아닙니다. 대신 계좌정보를 저장하지 않는 방식으로 조회를 제한합니다. 제한에 필요한 값은 서버 메모리에만 잠시 담기며, 이때도 계좌번호 원문이 아니라 SHA-256 해시와 조회 시각만 사용합니다. 데이터베이스에는 기록하지 않습니다.

제한 한도 목적
동일 계좌 재조회 5분당 1회 같은 계좌 반복 조회 방지
조회 횟수(성공 기준) 30분당 30회 정상 사용 범위 제한
요청 횟수(성공+실패) 30분당 60회 서버 보호 및 남용 차단

제한을 초과하면 429 응답과 함께 재시도까지 남은 시간이 반환됩니다.

429 응답 예시
{
  "success": false,
  "error": "ACCOUNT_COOLDOWN",
  "message": "동일 계좌는 5분에 1회만 조회할 수 있습니다. 잠시 후 다시 시도해 주세요.",
  "retryAfterSec": 540
}

이 카운터는 서버 메모리에만 존재하므로, 서버 인스턴스가 교체되면 초기화될 수 있습니다. 이는 이용자에게 불리하지 않은 방향(더 빨리 다시 조회 가능)이며, 무엇보다 고객 데이터를 남기지 않기 위한 의도적인 설계입니다.

5. 웹훅을 지원하지 않는 이유

적지 않은 분들이 웹훅(Webhook) 지원을 요청해 주셨습니다. "특정 계좌에 입금이 들어오면 자동으로 알림을 보내달라"는 것이죠. 정말 유용한 기능이고, 저희도 고민이 많았습니다.

하지만 웹훅으로 입금 알림을 보내려면, 저희가 다음을 지속적으로 저장하고 있어야 합니다.

  • 어떤 계좌를 감시할지 (계좌번호)
  • 그 계좌를 대신 조회하기 위한 비밀번호·인증정보

즉 웹훅은 본질적으로 "고객의 계좌정보와 자격증명을 우리 서버에 계속 저장해두는 것"을 전제로 합니다. 이는 저희의 무저장 원칙과 정면으로 충돌합니다.

저희의 선택: 이전에는 복호화가 불가능한 해시로 저장했고, 이제는 그 해시조차 저장하지 않습니다. 고객의 데이터를 저장하지 않는 것이 원칙이기에, 웹훅은 지원하지 않습니다. 편의보다 데이터를 남기지 않는 쪽을 택했습니다.

대안: 클라이언트 측 폴링

입금 확인이 필요하다면, 클라이언트가 필요한 시점에 직접 조회하는 폴링(polling) 방식을 권장합니다. 이 방식에서는 계좌정보가 요청하는 그 순간에만 전달되고, 저희는 아무것도 저장하지 않습니다. 구현 방법은 자동 입금확인 가이드쇼핑몰 자동 입금 확인 구현하기에서 자세히 다룹니다.

6. 마치며

기능을 하나 더 얹는 것보다, 남기지 않는 것이 더 어려운 결정일 때가 있습니다. 이번 업데이트는 그런 선택이었습니다. 계좌 등록을 없애 사용은 더 간단해졌고, 동시에 고객의 계좌정보는 저희 서버에 전혀 남지 않게 되었습니다.

가장 안전한 데이터는 저장하지 않은 데이터입니다. 앞으로도 편의를 위해 이 원칙을 타협하지 않겠습니다.

궁금한 점이 있으시면 문의하기로 언제든 연락 주세요.

관련 글