O que o Supabase fornece
Um valor:user.id, o uuid em auth.users. É esse o external_id.
lib/supabase.ts
getUser(), não getSession(). getSession() decodifica o cookie que o
navegador mandou — assinar o conteúdo dele seria assinar um valor que o navegador
escolheu. getUser() pergunta ao Supabase.A metade do servidor
app/api/userkit-boot/route.ts
401, e não um par vazio: “nenhum usuário” e “um usuário cujo
hash eu não consegui calcular” são situações diferentes, e o próximo passo de quem
chamou também é.
A metade do cliente
getState().verified só é true quando o HMAC conferiu. Logado no Supabase com
verified: false significa que o segredo é do outro ambiente ou que a mensagem
assinada não era exatamente o external_id.
Configuração
O que não viaja
Um usuário do Supabase carregaemail e email_confirmed_at. Nenhum dos dois
vira identidade no UserKit: um e-mail enviado pelo /v1/boot é guardado como
atributo, não resolve para um contato existente e não vira aresta de identidade. O
HMAC prova o external_id e só ele.
Para provar um endereço, mande um magic link ou um código por
e-mail — os dois fluxos que chegam nele.
O exemplo completo
Um app Next executável com esses arquivos, um
.env.example e as partes que esta
página deixa de fora.