Но что будет, если злоумышленник также украдет refresh token?
Не украдёт. JWT может быть не-httpOnly, чтобы его мог читать фронтенд. Следовательно, JWT можно украсть через XSS-дырку. refresh token должен быть всегда httpOnly и читать его может только сервер.
Второй уровень защиты — JWT ставится на .example.com, в то время как refresh токен ставится только на auth.example.com. Таким образом, даже если любой из твоих сервисов (кроме сервиса авторизации) будет скомпрометирован, refresh токен останется защищённым, т.к. не будет доступен никому кроме сервиса авторизации.
Да, это всё подразумевает, что как минимум refresh-токен нужно хранить защищённым от XSS, то есть точно не в localStorage, а в куках или чём-то подобном.