-
[Supabase][보안] secret API key incident 뒤 caller inventory와 verifier inventory를 어떤 대응표로 먼저 자르나기타개발지식/풀스택개발 2026. 8. 25. 09:16
IT 리서치 노트
[Supabase][보안] secret API key incident 뒤 caller inventory와 verifier inventory를 어떤 대응표로 먼저 자르나
Supabase secret API key incident가 나면 많은 팀이 dashboard에서 새 key를 만든 뒤 대응을 끝낸 것처럼 적는다. 반대로 JWT signing key 쪽 증상이 보여도 caller를 전부 다시 배포하는 식으로 범위를 넓히기도 한다. 하지만 2026년 8월 24일 기준 Supabase 공식 문서를 다시 보면 publishable·secret API keys와 JWT signing keys는 독립된 체계이고, API key migration 문서는 숨은 caller inventory를 먼저 찾으라고 적으며, signing key 문서는 Verify JWT와 verifier 경로를 별도로 점검하라고 안내한다. 이 글은 secret API key incident 뒤 caller inventory와 verifier inventory를 어떤 대응표로 먼저 자르는 편이 맞는지 정리한다.
1. 개요
결론부터 말하면 Supabase incident 첫 표는
caller inventory와verifier inventory두 개로 나누는 편이 가장 안전하다. secret API key 노출이면 caller inventory부터 열고, JWT signing key 문제면 verifier inventory부터 연다. 두 표를 한 장에 뭉치면 교체 대상과 검증 대상이 한꺼번에 흔들린다.caller inventory는 누가 secret key를 실제로 호출에 쓰는지 찾는 표이고, verifier inventory는 누가 JWT kid, JWKS, Verify JWT 경로를 검증하는지 찾는 표다. 이 둘은 둘 다 보안 대응처럼 보이지만 시작 질문이 전혀 다르다.
2. 어디서 실제로 막히는가
현장에서 가장 흔한 실패는 secret key 사고와 signing key 사고를 같은 회의록으로 적는 것이다. 그러면 어떤 팀은 caller를 이미 새 key로 바꿨는데도 verifier cache purge를 같이 하느라 장애 범위를 넓힌다. 반대로 signing key 문제인데 배포 경로만 계속 돌리느라 실제 검증 실패 지점을 못 찾기도 한다.
두 번째 실패는 caller inventory를 웹서버 몇 대로만 이해하는 것이다. API key migration 문서는 CI/CD, webhook, cron, worker process, Edge Functions까지 같이 보라고 적는다. 즉 hidden caller가 빠지면 새 key를 만들고도 old secret이 여전히 살아남을 수 있다. incident note에 caller inventory 칸이 좁으면 꼭 이 누락이 반복된다.
세 번째 실패는 verifier inventory를 gateway 하나로 축소하는 것이다. signing key 쪽 문제는 custom verifier, JWKS cache, Verify JWT 설정, Edge Functions auth path처럼 검증자가 분산될 수 있다. 어떤 곳은 새 kid를 읽는데 어떤 곳은 stale kid를 계속 본다면, caller cutover가 끝나도 로그는 계속 실패처럼 보인다.
마지막으로 revoke 시점을 inventory 완료 시점과 섞는 것도 위험하다. caller inventory는 old secret 마지막 호출 시각이 중요하고, verifier inventory는 새 signing key 첫 성공 시각과 cache 만료창이 중요하다. 이 두 타임라인을 한 줄로 적으면 어느 조건이 충족돼야 revoke해도 되는지 불명확해진다.
- 증상: key를 바꿨는데도 일부 경로가 계속 old secret이나 stale kid를 쓴다.
- 실패: secret key 사고와 signing key 사고를 같은 대응표에서 굴린다.
- 막힘: caller inventory에서 hidden caller를 빼거나 verifier inventory에서 cache 경로를 뺀다.
- 누락: revoke 시점을 caller 완료와 verifier 완료 중 무엇에 묶을지 안 적는다.
질문 먼저 열 표 대표 항목 노출된 값이 secret key인가 caller inventory server, webhook, cron, worker, Edge Function 새 kid 검증이 엇갈리는가 verifier inventory gateway, JWKS cache, custom verifier, Verify JWT path 기존 키 revoke를 언제 하나 shared timing row first success, last legacy hit, cache window 3. 실무에서 적용하는 순서
가장 짧은 실행 순서는 다섯 단계다. 첫째, 노출된 값이 secret key인지 signing key인지 먼저 분류한다. 둘째, secret key면 caller inventory를 열어 hidden caller까지 채운다. 셋째, signing key면 verifier inventory를 열어 cache와 Verify JWT 경로를 채운다. 넷째, old secret 마지막 호출 시각과 새 kid 첫 성공 시각을 서로 다른 값으로 남긴다. 다섯째, revoke는 해당 표의 종료 기준이 채워진 뒤에만 진행한다.
- 노출된 값이 secret key인지 signing key인지 먼저 자른다.
- secret key면 caller inventory를 hidden caller까지 채운다.
- signing key면 verifier inventory를 cache와 함수 경로까지 채운다.
- first success와 last legacy hit를 분리해 적는다.
- revoke는 해당 표의 종료 기준이 맞을 때만 한다.
- 배포 설정을 확인하고 caller 권한을 조회하고 env 파일 위치를 저장한다.
- webhook, cron, worker 로그를 조회하고 old secret 오류 응답을 파일로 저장한다.
- Verify JWT 설정을 확인하고 custom verifier 로그와 cache 상태를 조회한다.
- 콘솔 메모에 revoke 명령, 응답, 마지막 legacy hit 시각을 저장한다.
이 순서대로 가면 key 종류가 달라질 때도 운영 문서가 흔들리지 않는다. secret API key 사고는 caller cutover 중심으로, signing key 사고는 verifier consistency 중심으로 읽으면 된다. 두 표를 함께 보더라도 어느 표가 먼저인지 메모 첫 줄에서 정해 두는 편이 중요하다.
실무 연결로는 secret API key rotation과 signing key rotation을 분리한 글, JWKS cache window 글, verify_jwt false 종료 기준 글, 긴급 revoke와 cache purge 글을 함께 묶어 두면 branch가 자연스럽게 이어진다.
4. 공식 문서와 예시 화면으로 확인하기
첫 공식 자료는 Supabase signing keys 문서의 핵심 문장이다. publishable·secret API keys와 JWT signing keys는 서로 독립된 체계라고 분명히 적혀 있다.
즉 incident 첫 줄에서 노출된 값이 secret key인지 signing key인지 먼저 자르는 이유가 여기서 나온다. 둘을 같은 대응표에 섞으면 caller 교체와 verifier 검증을 동시에 흔들게 된다.
두 번째 화면은 Verify JWT 경고 구간이다. signing key rotation을 진행할 때 Edge Functions Verify JWT 설정을 무심코 두면 앱이 깨질 수 있다는 안내가 보인다.
이 문장은 verifier inventory가 왜 따로 필요한지 보여 준다. caller key를 바꾸는 일과 함수가 어떤 JWT 검증 경로를 타는지 확인하는 일은 다른 작업이다.
세 번째 자료는 새 API key migration 문서의 caller inventory 경고다. 여기서는 CI/CD, webhooks, cron jobs, worker processes 같은 비가시적 caller를 놓치지 말라고 적는다.
이 문장을 incident 대응표에 넣으면 caller inventory가 단순히 웹앱 서버 몇 개를 적는 표가 아니라는 점이 드러난다. 이미 secret API key rotation과 signing key rotation을 분리한 글을 읽었다면, 이번 글은 그 다음 단계인 대응표 설계다.
실무에서는 inventory를 두 표로 갈라 두는 것이 가장 빠르다. caller inventory는 누가 secret key를 쓰는지 찾는 표이고, verifier inventory는 누가 JWT kid와 JWKS를 검증하는지 찾는 표다.
이 표를 기준으로 적으면 secret key leak인데 verifier cache purge부터 건드리거나, signing key 문제인데 caller 교체만 반복하는 실수를 줄일 수 있다. JWKS cache window 글과 verify_jwt false 종료 기준 글이 각각 verifier 쪽 세부 분기로 이어진다.
마지막 자료는 incident 메모 예시다. 어떤 표를 먼저 열어야 하는지 메모 첫 줄에서 갈라 두면 회의도 짧아진다.
이 정도 메모면 key type 분류, caller cutover, verifier 검증, revoke 순서를 서로 다른 상태로 계속 유지할 수 있다. 402의 넓은 분류 글에서 막히던 독자를 바로 다음 분기인 대응표 설계로 넘기기에도 좋다.
5. 주의사항과 리스크
첫 번째 리스크는 secret key 사고에 verifier 작업을 과하게 붙여 장애 범위를 넓히는 것이다. 두 번째 리스크는 signing key 문제인데 caller 교체만 반복하는 것이다. 세 번째 리스크는 hidden caller와 stale verifier를 각각 한두 개씩 빼먹고도 revoke를 먼저 진행하는 것이다.
운영 전에 확인할 때는 최소한
leaked value type,primary table,last legacy hit,first new success네 줄은 남기는 편이 좋다. 이 네 줄이 없으면 다음 담당자는 다시 key 분류부터 시작하게 된다.- caller inventory와 verifier inventory는 다른 질문에 답하는 표다.
- hidden caller와 stale verifier를 각각 별도 누락 포인트로 본다.
- revoke는 표가 닫힌 뒤에만 진행한다.
6. 결론
Supabase incident 대응표에서 먼저 갈라야 할 것은 컴포넌트 목록이 아니라 key 종류와 inventory 종류다. secret API key 노출이면 caller inventory를, signing key 문제면 verifier inventory를 먼저 열면 된다. 이 분기만 고정해도 대응 범위가 훨씬 짧아진다.
이 분기까지 정리했다면 다음 단계는 hidden caller 차단과 stale verifier 재기동 순서를 정리한 후속 글로 넘어가면 된다. /407이 범위를 나누는 글이라면 /410은 incident 종료 순서를 닫는 글이라서 runbook을 한 단계 더 구체화할 수 있다.
- secret key면 caller inventory부터 연다.
- signing key면 verifier inventory부터 연다.
- first success와 revoke gate를 다른 줄로 남긴다.
7. 참고 링크
'기타개발지식 > 풀스택개발' 카테고리의 다른 글