ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Supabase][인증] signing key rotation 뒤 getClaims는 정상인데 custom verifier만 stale일 때 cache purge와 fallback 경로를 어떤 순서로 분리하나
    기타개발지식/풀스택개발 2026. 8. 17. 20:18

    IT 리서치 노트

    [Supabase][인증] signing key rotation 뒤 getClaims는 정상인데 custom verifier만 stale일 때 cache purge와 fallback 경로를 어떤 순서로 분리하나

    Supabase signing key rotation 뒤 getClaims는 바로 정상인데 custom verifier만 stale로 남는 순간이 있다. 2026년 8월 17일 기준 Supabase 공식 문서를 다시 보면 signing key와 JWKS는 multi-level cache를 전제로 하고, getClaims는 JWKS 기반 빠른 검증 또는 Auth server fallback 경로를 가진다. 이 글은 getClaims는 통과하는데 custom verifier만 stale일 때 cache purge와 fallback 경로를 어떤 순서로 분리해야 회복 범위를 덜 헷갈리는지 정리한다.

    1. 개요

    결론부터 말하면 signing key rotation 뒤 getClaims가 정상이라는 사실만으로 모든 verifier가 회복됐다고 보면 안 된다. getClaims는 JWKS 기반 빠른 검증 또는 Auth server fallback 경로를 타고, custom verifier는 앱이 직접 관리하는 캐시와 배포 수명에 묶이기 때문이다.

    그래서 first question은 "rotation이 끝났는가"가 아니라 "지금 통과한 것이 어떤 verifier 경로인가"다. cache purge와 fallback 메모를 경로별로 분리해야 stale 범위를 짧게 자를 수 있다.

    2. 어디서 실제로 막히는가

    실무에서 가장 자주 꼬이는 실패는 네 가지다. 첫째, getClaims가 통과했으니 custom verifier도 곧 정상이겠지 하고 더 이상 kid를 확인하지 않는다. 둘째, Supabase가 안내하는 20분 대기를 모든 verifier의 회복 시각으로 오해한다. 셋째, custom verifier의 자체 JWKS cache와 getClaims의 cache 경로를 같은 줄에 적는다. 넷째, getClaims가 Auth server fallback으로 통과한 것인지 로컬 JWKS 검증으로 통과한 것인지 메모하지 않는다.

    Supabase signing keys 문서는 edge cache와 client memory cache, 그리고 urgent revoke 때 cache busting mechanism 필요성을 직접 설명한다. JWT 문서는 JWKS를 오래 캐시하지 말라고 적고, getClaims 문서는 asymmetric signing key가 아니면 Auth server 요청으로 간다고 설명한다. 이 셋을 같이 읽으면 stale 범위는 verifier마다 다르게 남을 수 있다는 뜻이 된다.

    • 증상: getClaims는 pass인데 custom verifier만 옛 kid를 계속 본다.
    • 실패: getClaims 성공을 verifier 전체 성공으로 적는다.
    • 막힘: getClaims fallback과 custom verifier cache를 같은 메모에 섞는다.
    • 누락: kid 갱신 시각과 purge 시각과 회복 시각을 따로 적지 않는다.

    이미 Edge Functions와 custom backend verifier cache window 글로 정상 rotation의 시간 창을 잡았다면, 이번 글은 그다음 좁은 실패다. 같은 rotation인데 getClaims는 정상이고 custom verifier만 stale일 때 무엇부터 다시 확인하느냐가 핵심이다.

    3. 실무에서 적용하는 순서

    가장 실용적인 확인 순서는 다섯 단계다. 먼저 현재 요청이 getClaims 로컬 JWKS 검증인지 Auth server fallback인지 적는다. 두 번째로 custom verifier 로그에서 현재 kid를 확인한다. 세 번째로 앱 자체 JWKS cache purge 경로를 실행하고 시각을 적는다. 네 번째로 purge 뒤에도 stale이면 배포 수명이나 프로세스 재시작 경로를 분리한다. 마지막으로 그 뒤에야 Supabase 쪽 rotation 문제인지, 앱 verifier 문제인지 결론을 낸다.

    1. getClaims가 로컬 JWKS 검증인지 fallback인지 적는다.
    2. custom verifier가 보는 kid를 로그에서 확인한다.
    3. 앱 JWKS cache purge 시각을 기록한다.
    4. 배포 수명과 프로세스 cache를 분리해 확인한다.
    5. 그 뒤에만 Supabase rotation 회귀 여부를 판단한다.

    실제 운영에서는 현재 kid를 조회하고, getClaims 응답을 저장하고, fallback 여부를 확인하고, custom verifier cache를 purge하고, 프로세스를 다시 배포하고, 회복 시각을 다시 비교해야 한다. 같은 검증처럼 보여도 로컬 JWKS 검증과 Auth server 요청과 앱 자체 cache는 각각 확인하고, 저장하고, 다시 조회하고, 다시 비교하는 순서를 따로 가져가야 한다. 로그를 확인하고, 응답을 복사하고, cache purge 경로를 실행하고, 배포 시각을 저장하고, kid 변화를 다시 검증하는 메모가 필요하다.

    • getClaims mode와 custom verifier kid를 같은 표에서 비교한다.
    • cache purge 시각과 배포 재시작 시각을 분리 기록한다.
    • fallback 여부를 별도 필드로 남기고 다시 확인한다.
    • 회복 뒤에도 kid와 서명 검증 로그를 다시 저장한다.
    current_kid=key_2026_08_17
    getclaims_mode=jwks-local-verify
    getclaims_passed=true
    custom_verifier_seen_kid=key_2026_08_14
    custom_verifier_cache_purge=2026-08-17T11:12:10Z
    process_restart=2026-08-17T11:13:05Z
    recheck_at=2026-08-17T11:14:00Z

    이 순서를 지키면 getClaims 정상과 custom verifier stale을 같은 장애로 오래 끌지 않게 된다. 경로를 나누고, kid를 확인하고, purge를 실행하고, 회복 시각을 다시 비교하는 절차가 핵심이다.

    4. 공식 문서와 예시 화면으로 확인하기

    첫 공식 화면은 signing keys 문서의 urgent revocation 경고다. Supabase는 multi-level cache 때문에 애플리케이션 쪽에 cache busting mechanism이 필요할 수 있다고 직접 적고 있다.

    Supabase는 urgent revoke 상황에서 애플리케이션 백엔드에 cache busting mechanism이 필요할 수 있다고 설명한다.
    Supabase는 urgent revoke 상황에서 애플리케이션 백엔드에 cache busting mechanism이 필요할 수 있다고 설명한다.

    즉 문제는 rotation 자체보다 verifier별 캐시 경로다. 같은 시점에 getClaims는 통과하는데 custom verifier만 stale일 수 있는 이유가 여기서 시작된다.

    두 번째 자료는 rotation 가이드의 getClaims 안내다. Supabase는 legacy secret 의존을 줄이기 위해 getClaims 또는 적절한 JWT 검증 경로로 옮기라고 설명한다.

    Supabase는 signing key rotation 준비에서 getClaims 같은 검증 경로로 옮기라고 안내한다.
    Supabase는 signing key rotation 준비에서 getClaims 같은 검증 경로로 옮기라고 안내한다.

    이 문장이 중요한 이유는 verifier inventory를 가르는 출발점이 되기 때문이다. getClaims 경로와 custom verifier 경로는 같은 것처럼 보여도 회복 곡선과 fallback 방식이 다를 수 있다.

    세 번째 자료는 verifier 경로를 한 번에 나눠 보는 점검표다. getClaims와 custom verifier와 직접 Auth server 확인은 모두 JWT 검증처럼 보이지만 캐시 경로와 회복 신호가 다르다.

    getClaims와 custom verifier와 direct Auth check를 verifier inventory로 나눠 놓으면 stale 범위를 훨씬 빨리 줄일 수 있다.
    getClaims와 custom verifier와 direct Auth check를 verifier inventory로 나눠 놓으면 stale 범위를 훨씬 빨리 줄일 수 있다.

    즉 getClaims가 정상이라는 관찰은 JWKS 기반 경로가 최신 키를 봤다는 뜻일 뿐이다. custom verifier의 자체 캐시까지 회복됐다는 뜻은 아니다.

    네 번째 자료는 rotation 뒤 stale 범위를 자를 때 남기는 최소 메모 예시다. getClaims mode와 custom verifier kid와 purge 시각과 fallback 여부를 한 줄에 남기면 분기가 빨라진다.

    rotation 뒤 verifier별 stale 범위를 적을 때 남기면 좋은 최소 메모 예시다.
    rotation 뒤 verifier별 stale 범위를 적을 때 남기면 좋은 최소 메모 예시다.

    그래서 getClaims가 정상이라는 사실만으로 모든 verifier 회복을 단정하면 안 된다. 로컬 JWKS 검증인지, Auth server 요청 fallback인지부터 메모를 분리해야 한다.

    다섯 번째 자료는 rotation 뒤 재확인 순서를 한 줄로 모은 표다. getClaims mode와 custom verifier cache purge와 process restart를 분리해 적어야 stale 범위를 빠르게 줄일 수 있다.

    rotation 뒤 stale 범위를 줄일 때 바로 쓰는 재확인 순서 표다.
    rotation 뒤 stale 범위를 줄일 때 바로 쓰는 재확인 순서 표다.

    이미 긴급 revoke와 cache purge 순서 글로 사건 대응축을 잡았다면, 이번 표는 getClaims 정상과 custom verifier stale을 같은 회복으로 보면 안 되는 이유를 운영 메모 수준으로 좁힌다.

    마지막 자료는 fallback과 purge를 함께 적는 체크 메모다. rotation 뒤 stale 문제는 cache purge를 했는지, getClaims가 어떤 모드였는지, process를 다시 띄웠는지를 같이 적어야 복기가 된다.

    fallback과 purge와 재시작을 한 줄씩 남기는 운영 메모 예시다.
    fallback과 purge와 재시작을 한 줄씩 남기는 운영 메모 예시다.

    이 정도만 남겨도 getClaims 정상과 custom verifier stale을 같은 장애로 오래 묶지 않게 된다. 로컬 JWKS 검증인지, Auth server 요청 fallback인지부터 메모를 분리해야 한다.

    5. 주의사항과 리스크

    첫 번째 리스크는 getClaims가 통과했다는 이유로 custom verifier cache purge를 건너뛰는 것이다. 두 번째는 20분 대기를 모든 verifier의 회복 완료 시각으로 오해하는 것이다. 세 번째는 Auth server fallback 성공을 로컬 JWKS cache 회복으로 잘못 기록하는 것이다.

    운영 전에 확인할 때는 최소한 verifier 이름, verification mode, kid, cache purge 시각, fallback 여부, 회복 시각을 같은 incident 메모에 두는 편이 좋다. 그래야 stale 범위를 verifier별로 구분해 설명할 수 있다.

    • getClaims 성공은 custom verifier 회복 증거가 아니다.
    • fallback 경로와 로컬 JWKS 검증을 따로 기록한다.
    • kid와 purge 시각과 회복 시각을 verifier별로 남긴다.

    6. 결론

    Supabase signing key rotation 뒤 getClaims는 정상인데 custom verifier만 stale이라면, rotation 전체를 다시 의심하기보다 verifier 경로와 cache 수명을 먼저 갈라야 한다. getClaims mode와 custom verifier kid와 cache purge 시각을 분리해 적으면 stale 범위를 훨씬 빨리 자를 수 있다.

    • getClaims mode가 로컬 JWKS인지 fallback인지 먼저 적는다.
    • custom verifier가 본 kid와 purge 시각을 따로 확인한다.
    • 회복 뒤에도 verifier별 검증 로그를 다시 저장한다.

    후속 분기로는 Edge gateway verify_jwt와 custom verifier fallback 성공을 같은 회복 신호로 보면 안 되는 이유를 붙여 두면, stale custom verifier를 분리한 뒤 어떤 회복 신호를 incident 종료 기준으로 삼아야 하는지까지 바로 이어서 볼 수 있다.

    7. 참고 링크

    1. https://supabase.com/docs/guides/auth/signing-keys
    2. https://supabase.com/docs/guides/auth/jwts
    3. https://supabase.com/docs/reference/javascript/auth-getclaims
Designed by Tistory.