As quatro famílias
uk_st_… — sessão de staff
Uma pessoa logada no painel. Administra a organização. Vive 30 dias, revogável.
uk_sk_… — chave de API da organização
Seu backend. Lê e escreve no plano de clientes, delimitado ao ambiente da
chave.
uk_pk_… — chave publicável
Suas páginas. Pública por definição; a lista de origens é a fronteira dela.
uk_ct_… — sessão de contato
Um dos seus usuários. Lê o próprio contato e mais nada.
Authorization: Bearer, exceto a chave publicável, que
vai no corpo da requisição dos endpoints que a aceitam.
Nada mais é aceito como credencial. Nenhum parâmetro de query — cairia em logs de
acesso e no histórico do navegador. Nenhum cookie — esta API não é autenticada por
cookie, e é também por isso que o CORS nunca precisa de credenciais.
Apresentando a errada
Uma credencial bem formada de outra família recebe isso, em vez de um “inválido” seco:401
Sessões de staff
uk_st_…, emitidas por /v1/auth/signup, /v1/auth/login e
/v1/auth/two-factor. Válidas por 30 dias.
Longas porque são revogáveis. Sair, trocar a senha, redefinir a senha ou perder
o vínculo matam a sessão no servidor — ao contrário de um JWT autocontido, que
continua válido até expirar, não importa o que aconteça com a conta.
Chaves de API da organização
uk_sk_…, somente no servidor. Criadas no painel, mostradas uma vez, armazenadas
como hash.
revoked_at em vez de deletar a linha, então o rastro de auditoria
de quais chaves existiram não desaparece junto.
Chaves publicáveis
uk_pk_…, uma por ambiente, criada junto com ele, armazenada em texto puro —
porque uma chave publicável identifica e quase nada autoriza, e o painel precisa
conseguir mostrá-la de novo.
Ela fica no HTML da sua página por definição. O que impede um estranho que a leu de
inundar seu tenant com contatos-lixo é a lista de origens permitidas na linha
dela, mais um rate limit por chave no boot.
Origin ausente também é recusado: navegadores
sempre mandam um em requisição cross-origin, então “sem Origin” significa “não é um
navegador” — exatamente quem a lista existe para barrar.
Sessões de contato
uk_ct_…, a credencial do seu usuário, emitida pelo boot, por um magic link ou
código por e-mail resgatado, por login hosted ou por verificação de e-mail.
Válida por 30 dias.
Uma sessão de contato lê o próprio contato e mais nada. Esse escopo é todo o
modelo de autorização do uk_ct_.
verified — se a identidade por trás dela foi
comprovada:
Uma sessão não verificada é usável em desenvolvimento e fica marcada no painel, mas
é barrada de qualquer coisa por onde os dados de outra pessoa pudessem vazar.
Um contato consegue ver e encerrar as próprias sessões —
GET /v1/contact/sessions,
DELETE /v1/contact/sessions/{id}, e DELETE /v1/contact/sessions para todas as
outras. Isso faz parte da defesa do token, não é um extra: ele vive no seu domínio
sem httpOnly.
A única credencial não opaca
Tudo acima é opaco — uma string aleatória cujo significado vive no nosso banco. A exceção é o JWT de sessão: cinco minutos, ES256, assinado por ambiente, emitido a partir de uma sessãouk_ct_… em POST /v1/contact/token e verificado offline
pelo seu backend contra GET /v1/jwks/{publishable_key}.
Ele existe para a sua API não precisar chamar a nossa a cada requisição. E é curto
justamente porque não pode ser revogado. Veja
Tokens de sessão.
Tokens de uso único
Não são credenciais que você guarda, mas seguem o mesmo formato — um prefixo cada, para que nenhum possa ser confundido com uma sessão:O que é armazenado
Um dump do banco não entrega nenhuma credencial funcionando.