Loading...
태그
    supabasejwt

Supabase 비대칭 JWT 적용방법

최종수정일
2026년 01월 09일
4분걸림
작성자: Techy J
Table of Content (목차)

supabase에서 JWT 기반의 인증

정상적인 로그인이 완료되면 서버는 인증정보를 발급하고, 클라이언트는 그 정보를 브라우저 쿠키에 저장한다. 이후 클라이언트가 웹서버 내의 특정 경로를 접근하거나 DB서버의 자원에 접근할때, 서버는 클라이언트 요청에 포함된 JWT(Json Web Token) 내의 access_token에 인증정보를 평가하고 접근 권한에 따라 요청을 처리한다.

대칭키(Symmetric) JWT

인증정보는 인증서버에서 발급될때 암호화 되어 있다. 25년 7월 전까지 supabase auth 에서 사용하는 암호화 키는 대칭키 방식이었고, 인증서버와 클라이언트 간에 동일한 키를 사용한다. 그러므로 키가 유출되지 않도록 보안에 유의해야 했다. 또한, 이 방식에서는 클라이언트단에 가해진 변조 공격에 대비해 JWT를 직접 복호화하지 않고, 매번 사용자 정보를 확인해야 할 때 마다 서버로 supabase.auth.getUser() 를 호출하도록 했다. 때문에 네트워크 지연과 인증서버가 온라인 상태여야 하는 제약이 발생한다.

비대칭키(Asymmetric) JWT(25.7 월 추가)

25년 7월 supabase는 비대칭키 JWT를 발표했다. 비대칭키 방식은 비밀키와 공개키가 서로 다르고, 둘은 정해진 한쌍으로만 암호화와 복호화가 가능하다. 비밀키는 인증서버에서 JWT를 생성해서 서명을 추가할때 암호화에 사용하고, 공개키는 클라이언트에서 JWT를 복호화하고 검증하는 기능만 가능하므로 이름 그대로 공개되어도 보안에 문제는 없다. 인증서버만이 알고 있는 비밀키로 인증정보를 암호화하므로, 클라이언트가 직접 공개키를 이용해 supabase.auth.getClaims() 를 호출해 JWT내의 인증정보를 확인하도록 변경되었다.

supabase에서 대칭 JWT에서 비대칭 JWT 로 이전하는 방법(요약)

  • JWT Signing Keys 발급(standby key)
  • rotate 클릭해 standby keycurrent key 로 지정(클라이언트에서 JWT 복호화시 사용) JWT signing Keys- JWT signing Keys -
  • API Keys 아래 API Keys 의 Publishable key 값을 이전 ANON 키의 값으로 대체(클라이언트 용) API Keys- API Keys -
  • supabase.auth.getClaims() 호출해 정상동작 확인(클라이언트에서 ANON 키 사용)
  • 사용하지 않는 기존 키 삭제

웹앱에서 비대칭 JWT 로 변경하는 방법(상세)

위 요약의 내용 처럼 먼저 새로운 비대칭 JWT 발급을 위한 키를 생성해 current key로 설정한다. 서버가 signing 하는 키는 서버만 가지고 있고, current key는 JWT를 복호화 할 경우 사용한다. 이처럼 JWT 발급시 사용하는 키 값이 변경되면, 이후 발급하는 ANON이나 service key는 이 키를 기반으로 발급된다. 그러므로 supabase client를 생성할 때 사용하는 ANON 키 값도 새로 생성해 기존 키 값을 대체하는 것이 좋다. 마지막으로 supabase.auth.getClaims() 를 실행해서 인증정보를 확인한다. 변경 하는 도중에 키 변경이 잘 이루어졌는지 확인하고 싶으면, 아래 순서대로 비대칭 JWT 발급 후 기존 ANON 키를 사용하는 상태에서 getClaims() 동작을 확인한 후 마지막으로 새로운 ANON 키를 발급받아서 supabase client 가 정상동작하는지 확인해도 된다.

비밀키를 이용한 JWT 사용을 위한 migration

Project Setting > JWT Keys > JWT Signing Keys 에서 Migrate JWT secret 을 클릭하면, Standby Key(ECC P-256)와 Current Key(Legacy HS256 - Shared secret) 가 보인다.

이중 Standby Key의 정보를 보면 키 ID는 3xxxxxxxc-xxxx-xxxx-xxxx-xxxxxxxxxxxx 이다.

{
  "x": "0xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxw",
  "y": "txxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8",
  "alg": "ES256",
  "crv": "P-256",
  "ext": true,
  "kid": "3xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "kty": "EC",
  "key_ops": [
    "verify"
  ]
}

이 키가 들어 있는 JSON 파일은 view key details 정보를 보면

https://exxxxxxxxxxxxxxxxxxp.supabase.co/auth/v1/.well-known/jwks.json

에서 찾을 수 있다. URL의 exxxxxxxxxxxxxxxxxxp 는 각자의 supabase project ID 이다. migration을 완료하면 새로운 Signing 키를 생성해 standby로 만든 상태며, 아직 비대칭 JWT가 발급되는 건 아니다.

비대칭 JWT 활성화를 위한 rotate 실행

rotate 를 클릭하면 Supabase Auth 가 비밀키로 암호화된 JWT를 발급하기 시작하고, standby keycurrent key 가 된다. 이전의 current keyprevious key 영역에 저장된다. 뭔가 문제가 있어서 이전 키를 다시 사용해야 할때는 previous key 를 다시 standby key 로 이동시킨 후 rotate 해서 다시 사용할 수 있다. 즉 키의 생성에서 활용과 종료의 순은 아래와 같다.

standby key ⟶ current key ⟶ previous key ⟶ standby key

클라이언트에서 current key 의 KEY ID 를 이용하면 JWT 를 복호화 할 수 있다. Previous key를 이용해 아직 expire 되지 않은 token 들을 검증할 수 있는데, 이 키를 revoke를 하면 모든 token들이 expire 된다. revoke 된 키는 7일 후 영구삭제된다.

비대칭 JWT 적용

클라이언트 코드에서 JWT 복호화를 하지 않으면 비대칭 JWT를 적용해도 변경할 부분은 없다. 하지만, JWT 를 디코딩이 필요한 경우는 SUPABASE_JWT_KEY를 rotate 후 current key 의 KEY ID 를 바로 이용하기 보다는 키 변조 등의 위협에 대비하기 위해 current keyDiscovery URL 에서 받아서 사용한다.

supabase.auth.getUser() 대신에 supabase.auth.getClaims() 를 사용한다. 변경후 network 을 확인하면 server 요청이 발생하지 않는다.

const supabase = createClient();
const { data, error } = await supabase.auth.getClaims();
console.log('[getClaims]: ', data?.claims.app_metadata.role);
const role = data?.claims.app_metadata.role;
return role;

만일 getClaims() 를 인식하지 못하는 경우 아래와 같이 패키지를 업데이트한다.

npm update @supabase/supabase-js

ANON 및 service_role 키 변경

ANON 키는 supabase 클라이언트를 생성할 때 사용한다. service_role 키는 Row Level Security 를 bypass 할때 사용한다. 이 두 키는 프로젝트 생성과 동시에 만들어지며 10년 후에 expire 된다. 이키들은 비대칭 JWT를 사용하면 더 이상 동작하지 않으므로 새로운 API 키를 사용해야한다. API 키에는 ANON, service_role 키가 있으며 아래에서 생성한다.

Settings ⟶ API Keys ⟶ API Keys ⟶ Create new API keys

ANON 는 생성된 API Keys에서 Publishable Key 를 사용하고, .env 파일이나 .env.local 에 키를 정의한다. service_role 키는 Secret Keys를 사용한다.

API 키 revoke 및 JWT 키 revokeㅏ

위처럼 새로운 키들이 적용에서 모든 기능이 정상동작임을 먼저 확인 후 기존 키들을 삭제한다. legacy API 키 부터 Disable JWT-based API keys 하고 JWT 키를 revoke 하는 순서로 진행한다. 문제가 있으면 re-eanble도 가능하다.

This disables API keys when used in the apikey header. They remain valid as a JWT.

다음으로 Previous KEY 를 revoke 한다. 이전 legacy JWT 로 sign in 되어 있는 사용자들은 sign out 된다.

(끝)

이 글은 ' 출처: 변호사 전정숙 '과 ' 원본링크: https://www.korean-lawer.com/articles/데이터베이스/supabase-비대칭-jwt-적용방법'를 명시하는 조건으로 인용가능 합니다.
무단 복제, AI 학습 목적으로의 사용과 Google, Naver의 Indexing 외 크롤링 금지합니다
About
전정숙 변호사
법무법인 정맥 파트너 변호사부산파산법원 파산관재인전) 부산변호사회 부회장전) 전국여성변호사회 부회장전) 부산 가정법원 조정위원
Contact

(82) 051-916-8582 , 051-916-8583

부산광역시 연제구 법원로 12 (거제동)

로윈타워빌딩 2층 법무법인정맥

변호사 전정숙

© 2005-2026 전정숙 변호사.

All Rights Reserved.