Skip to main content
Suas páginas guardam uma sessão de contato uk_ct_…. O seu backend precisa saber quem está chamando, e perguntar para a gente a cada requisição colocaria a nossa latência e a nossa disponibilidade na frente da sua API. Então a sessão de contato compra um JWT de vida curta, assinado por ambiente, que o seu backend verifica offline contra um conjunto de chaves públicas.
Duas credenciais, dois trabalhos. A sessão opaca é de vida longa e revogável. O JWT é de vida curta e irrevogável, e é exatamente por isso que ele é curto.

Emitindo

Este é o fluxo de refresh, e não há uma segunda credencial para gerenciar: a sessão opaca é o refresh token. Chame de novo sempre que o último JWT estiver perto de expirar, enquanto a sessão viver.
Cada emissão registra o contato no medidor de contatos ativos do mês, de forma idempotente. É esse o número que a sua fatura lê — veja o medidor.

O que o token carrega

string
O id do ambiente. Fixe ele. Um token do ambiente de teste não pode satisfazer uma verificação de produção.
uuid
O id do contato.
uuid
O id da sessão — o que você passa para DELETE /v1/contact/sessions/{id}.
string
O seu próprio id para essa pessoa, presente quando o contato tem um. No modo federado é nele que o seu backend se apoia.
string
boolean
Se a identidade por trás da sessão foi comprovada. Barre nisso antes de qualquer coisa por onde os dados de outra pessoa pudessem vazar — um token com verified: false é uma assinatura perfeitamente válida sobre uma afirmação não comprovada.
integer
Segundos Unix. A validade é de 5 minutos.

Verificando

Busque o conjunto de chaves uma vez, guarde em cache, e verifique localmente.
Endereçado pela chave publicável — o único identificador que o seu backend já tem na config. Público e sem autenticação por definição: são chaves públicas. Também não há portão de Origin, porque quem chama é um servidor, e servidores não mandam Origin.
Verifique a assinatura. Não leia o payload sem ela — um JWT é base64, não é criptografia, e qualquer coisa pode ser digitada dentro de um.

Guarde o conjunto de chaves em cache

A resposta carrega:
Isso é deliberado. Um verificador precisa continuar verificando durante os nossos cinco minutos ruins, então um CDN ou um cache em processo deve seguir respondendo enquanto uma nova busca é tentada. A maioria dos clientes de JWKS respeita isso sozinha; os acima respeitam. As chaves são criadas na primeira leitura, então o documento nunca fica vazio para um ambiente configurado. Quando a emissão de JWT está indisponível no servidor, a resposta é um conjunto vazio em vez de um erro — o formato continua válido, e é o POST /v1/contact/token que devolve o 501 jwt_unavailable.

Revogação, e os cinco minutos

Um JWT é verificado offline, então nada consegue chamá-lo de volta. Deletar uma sessão interrompe o próximo refresh, não o token que já está numa página. Isso faz de cinco minutos o tempo máximo que uma sessão revogada continua funcionando — e é toda a razão de a credencial de vida longa ser a opaca e revogável, e a de vida curta ser a assinada. Se você precisa de revogação imediata para uma ação específica, confira a sessão no servidor para aquela ação, em vez de alongar o JWT.

Sessões que o contato enxerga

O token de sessão de contato vive no seu domínio sem httpOnly. Isso faz de “ver meus dispositivos e encerrar um” parte da defesa desse token, não um extra.
Revogar é deletar — imediato, com a validade do JWT como único rastro. “Sair de todos os outros” mantém a sessão que pediu. O id de sessão de outro contato e um que nunca existiu respondem o mesmo 404.

Rotacionando a chave de assinatura

Exige api_keys:write — a mesma trava do segredo de identidade, porque essa chave emite os tokens em que o seu backend confia. A chave antiga para de assinar na hora e continua verificando por 24 horas: a sobreposição que permite aos caches de JWKS se atualizarem e aos tokens em voo expirarem. Seu backend não precisa de deploy — ele rebusca o conjunto de chaves e encontra os dois kid. Numa suspeita de comprometimento a conta corre ao contrário: todo token assinado com a chave antiga morre em até 5 minutos da rotação. É esse o limite a citar.

O medidor de contatos ativos

Exige customers:read. Um contato conta como ativo num mês quando um JWT é emitido para ele — então uma sessão aberta em janeiro e renovada em fevereiro está ativa nos dois. Só o ambiente live, porque só contatos de produção contam. O mês é UTC, decidido uma vez no schema: a exibição pode traduzir, uma fatura não pode ser ambígua. Isso lê a mesma consulta que a fatura lê.