ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Supabase][인증] JWT signing key rotation 전에 Edge Functions Verify JWT와 getClaims 전환을 어디부터 나누나
    기타개발지식/풀스택개발 2026. 8. 14. 09:19

    IT 리서치 노트

    [Supabase][인증] JWT signing key rotation 전에 Edge Functions Verify JWT와 getClaims 전환을 어디부터 나누나

    Supabase에서 JWT signing key rotation을 준비할 때 많은 팀이 standby key 생성과 rotate 버튼만 본다. 하지만 2026년 8월 14일 기준 Supabase 공식 문서를 다시 보면 Edge Functions의 Verify JWT 설정이 켜져 있으면 회전이 앱을 깨뜨릴 수 있고, `supabase.auth.getClaims()` 사용 여부와 직접 JWKS 검증 코드 존재 여부까지 같이 봐야 한다. 이 글은 signing key rotation 전에 무엇부터 어떤 순서로 분리해야 downtime을 줄일 수 있는지 정리한 것이다.

    1. 개요

    결론부터 말하면 Supabase JWT signing key rotation 전 점검은 Edge Functions Verify JWT 설정, getClaims() 사용 여부, 직접 JWKS 또는 shared secret 검증 코드를 먼저 갈라 적는 편이 맞다. rotation 자체는 새 standby key를 current key로 바꾸는 동작이지만, 앱이 실제로 어디서 JWT를 검증하는지는 별도 문제다.

    그래서 key 생명주기만 보고 바로 rotate하면 일부 경로는 새 JWT를 받고도 검증이 실패할 수 있다. 앱 쪽 검증자가 준비됐는지, 캐시가 새 key를 볼 수 있는지까지 확인한 뒤에야 rotate와 revoke 순서가 안전해진다.

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

    현장에서 가장 자주 꼬이는 실수는 세 가지다. 첫째, Edge Functions Verify JWT 토글을 켠 채 signing key rotation을 진행한다. 둘째, Supabase client library를 쓰는 경로와 직접 jose 검증 코드를 쓰는 경로를 같은 것으로 적는다. 셋째, rotate 후에도 기존 JWT가 잠시 유효하다는 점과 JWKS 캐시 반영 시간을 운영 메모에 남기지 않는다.

    Supabase signing keys 문서는 standby key 생성 뒤 rotate를 수행하면 새 JWT는 새 key로 서명되지만 이전 key도 일정 기간 신뢰 관계 안에 남는다고 설명한다. 동시에 Edge Functions의 Verify JWT 설정이 켜져 있으면 회전이 앱을 깨뜨릴 수 있으니, supabase.auth.getClaims()나 JWT verification 가이드를 참고해 검증 코드를 바꾸라고 안내한다. 즉 키 교체와 검증 경로 전환은 한 묶음이지만 서로 다른 체크리스트를 가진다.

    JWT verification 가이드는 JWKS endpoint와 createRemoteJWKSet 예시를 제시하고, HS256 shared secret 검증은 가능하지만 권장하지 않는다고 적고 있다. 이 차이를 놓치면 어떤 서버는 공개키 기반으로, 어떤 Edge Function은 old Verify JWT 토글에 기대는 상태로 남아 회전 직후 증상이 갈라진다.

    • 증상: rotate 직후 일부 Edge Function이나 API가 새 JWT를 거부한다.
    • 실패: Verify JWT 토글과 앱 코드 검증 방식을 한 줄로만 적는다.
    • 막힘: Supabase client library와 직접 JWKS 검증을 같은 캐시 동작으로 가정한다.
    • 누락: revoke 전 유예 시간과 캐시 반영 시간을 메모에 안 남긴다.
    증상 먼저 볼 곳 판단 기준
    회전 직후 Edge Function 호출 실패 Verify JWT 설정 rotation 전에 토글과 검증 코드 전환을 했는지 본다
    일부 서버만 새 JWT 검증 실패 JWKS 캐시 새 standby key가 verifier 캐시에 반영됐는지 본다
    shared secret 검증 경로가 오래 끌린다 HS256 직접 검증 Auth server 또는 공개키 기반 경로로 바꿀지 본다

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

    가장 실용적인 순서는 다섯 단계다. 먼저 rotation 대상이 signing key branch인지 확실히 적는다. 두 번째로 Edge Functions의 Verify JWT 토글이 켜져 있는 경로를 찾는다. 세 번째로 supabase.auth.getClaims()를 쓰는 경로와 직접 jose 또는 자체 verifier를 쓰는 경로를 나눈다. 네 번째로 standby key를 만든 뒤 JWKS 캐시 반영 시간과 access token 수명을 기록한다. 마지막으로 rotate 후 revoke는 유예 시간을 지킨 뒤에만 진행한다.

    1. 지금 문제가 signing key branch인지 먼저 적는다.
    2. Verify JWT 토글이 켜진 Edge Function 목록을 찾는다.
    3. getClaims() 경로와 직접 verifier 경로를 분리한다.
    4. standby key 생성 뒤 JWKS 캐시와 token TTL을 기록한다.
    5. rotate 후 revoke는 유예 시간과 캐시 반영 후에 진행한다.

    Supabase 문서는 access token expiry가 1시간이면 revoke 전 최소 1시간 15분 대기를 예로 들고 있다. 또 discovery endpoint는 edge 서버와 client library 메모리 캐시 때문에 다단계 캐시를 가질 수 있다고 설명한다. 따라서 rotate만 성공했다는 사실과 전체 검증자가 새 key를 보기 시작했다는 사실은 다르다.

    운영 중에는 대시보드 설정을 열어 Verify JWT 토글을 확인하고, 함수 파일 이름과 API gateway 설정 파일을 조회하고, 콘솔 로그와 오류 응답을 저장해야 한다. rotate 명령을 실행하기 전후로 JWKS 캐시 시간, token TTL, verifier 로그, 실패 응답 코드를 같은 메모에 기록하면 재현과 비교가 훨씬 빨라진다.

    전환 메모 예시
    signing_key_state=standby_created
    edge_verify_jwt_paths=functions/report-webhook, functions/admin-sync
    claims_mode=getClaims on app server
    direct_verifier=jose+JWKS on api-gateway
    token_ttl=3600
    revoke_after=75_minutes_and_cache_check

    이 구조를 잡아 두면 key rotation 이후 증상이 어느 검증 경로에서 나는지 금방 보인다. 이미 publishable·secret·service_role 분리 글과 backend별 secret key rotation 글을 읽었다면, 이번 글은 JWT signing branch만 따로 좁히는 후속편이다.

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

    첫 실제 자료는 signing keys 문서의 경고 구간이다. Supabase는 Edge Functions의 Verify JWT 설정을 켠 상태에서 회전을 이어가면 앱이 깨질 수 있다고 직접 경고한다.

    Supabase Docs는 signing key rotation 전에 Edge Functions Verify JWT 설정과 JWT 검증 코드를 함께 다시 보라고 안내한다.
    Supabase Docs는 signing key rotation 전에 Edge Functions Verify JWT 설정과 JWT 검증 코드를 함께 다시 보라고 안내한다.

    이 문장 덕분에 key rotate 버튼을 누르기 전 점검 범위가 명확해진다. 단순히 새 standby key를 만드는 일과 Edge Functions 검증 방식 전환은 같은 버튼으로 끝나지 않는다.

    두 번째 자료는 key 생명주기다. Supabase는 새 키가 standby로 시작하고, rotate 이후에는 이전 키도 한동안 함께 신뢰된다고 설명한다.

    signing key는 standby → in use → previously used 흐름을 가지며 rotate 뒤 한동안 두 키를 모두 신뢰한다.
    signing key는 standby → in use → previously used 흐름을 가지며 rotate 뒤 한동안 두 키를 모두 신뢰한다.

    즉 애플리케이션 전환이 끝나기 전에 바로 revoke부터 가는 편은 위험하다. 특히 자체 JWT 검증 캐시를 쓰는 경로가 있으면 새 public key 반영 시간이 incident 범위를 바꾼다.

    세 번째 자료는 Supabase JWT 검증 예시다. 문서는 JWKS endpoint와 `createRemoteJWKSet` 기반 검증 코드를 보여 준다.

    Supabase는 JWKS endpoint 기반 JWT 검증 예시를 제공하며, 자체 검증 코드라면 이 경로와 캐시를 같이 봐야 한다.
    Supabase는 JWKS endpoint 기반 JWT 검증 예시를 제공하며, 자체 검증 코드라면 이 경로와 캐시를 같이 봐야 한다.

    rotation 때 중요한 것은 키 값 자체보다 검증자가 어느 endpoint와 캐시 정책을 쓰는지다. Supabase client library를 쓰는지, 직접 jose 검증 코드를 돌리는지에 따라 전환 메모가 달라진다.

    실무에서는 key rotation 전 점검표가 먼저다. Verify JWT 토글, `getClaims()` 사용 여부, 직접 JWKS 검증 코드 존재 여부를 같은 표에 두면 빠르다.

    Edge Functions Verify JWT, getClaims, 직접 JWKS 검증 경로를 함께 적는 체크리스트다.
    Edge Functions Verify JWT, getClaims, 직접 JWKS 검증 경로를 함께 적는 체크리스트다.

    이미 secret key rotation과 signing key rotation 분리 글이 큰 분기를 다뤘다면, 이번 코드는 signing key branch 안쪽 점검 순서다.

    같은 JWT 문제처럼 보여도 Verify JWT 토글, JWKS 캐시, HS256 직접 검증은 서로 다른 대응을 요구한다. 분기표를 먼저 두면 rotate 버튼을 누르기 전 할 일이 정리된다.

    Verify JWT 설정, JWKS 검증, HS256 직접 검증을 분리한 triage 표다.
    Verify JWT 설정, JWKS 검증, HS256 직접 검증을 분리한 triage 표다.

    이 표 덕분에 key rotation 문제를 token 만료 문제나 publishable key 문제와 섞지 않게 된다. JWT 검증 경계는 API key 경계와 따로 다뤄야 한다.

    5. 주의사항과 리스크

    첫 번째 리스크는 Edge Functions Verify JWT 토글을 건드리지 않은 채 rotation을 진행하는 것이다. 두 번째 리스크는 shared secret 검증 경로를 그대로 둔 상태에서 revoke를 서두르는 것이다. 세 번째 리스크는 JWKS 캐시와 token TTL을 기록하지 않아 일부 서비스만 실패한 원인을 네트워크 문제처럼 오해하는 것이다.

    • rotate 성공과 verifier 전환 완료는 같은 사건이 아니다.
    • Verify JWT 토글, getClaims(), 직접 verifier는 분리해서 기록한다.
    • revoke는 cache와 token TTL 확인 뒤에만 진행한다.

    6. 결론

    Supabase JWT signing key rotation은 standby key를 만드는 순간보다 검증 경로를 분리하는 순간이 더 중요하다. Edge Functions Verify JWT, getClaims(), 직접 JWKS 검증 코드를 먼저 정리하고 rotate와 revoke를 나누면 downtime을 크게 줄일 수 있다.

    • rotation 전 Verify JWT 설정과 verifier inventory를 만든다.
    • JWKS 캐시와 token TTL을 기록한다.
    • revoke는 유예 시간 이후에만 진행한다.

    7. 참고 링크

    1. https://supabase.com/docs/guides/auth/signing-keys
    2. https://supabase.com/docs/guides/auth/jwts
    3. https://supabase.com/docs/guides/getting-started/api-keys
Designed by Tistory.