TL;DR: Filippo Valsorda propôs um formato interoperável para armazenar passkeys como strings opacas, de maneira parecida com hashes de senha, e esboçou uma API crypto/passkey para Go. A ideia reduz o acoplamento entre o esquema do banco e uma biblioteca WebAuthn, mas ainda está em fase de discussão: não há implementação nem proposta formal aceita para a biblioteca padrão.
O problema está no servidor, não só no navegador
Passkeys usam WebAuthn e criptografia de chave pública para autenticar pessoas sem depender de um segredo digitado que possa ser entregue a um site de phishing. O navegador e o autenticador cuidam de boa parte da cerimônia, mas o backend ainda precisa guardar informações da credencial e verificar cada login.
A especificação WebAuthn descreve o registro de uma credencial como um conceito formado por campos como identificador, chave pública, transportes e estado de backup. Ela não define, porém, uma representação única para persistência. Na prática, cada aplicação ou biblioteca pode escolher seu próprio conjunto de colunas e sua própria serialização.
Isso cria atrito operacional. Trocar a biblioteca WebAuthn, mover o serviço para outra linguagem ou unificar autenticação entre sistemas pode exigir migração do banco e conversão de dados criptográficos. Também força a aplicação a conhecer detalhes que poderiam ficar encapsulados na camada de autenticação.
A proposta tenta preencher justamente essa lacuna: definir um registro que possa ser armazenado e transportado sem que o restante da aplicação precise interpretar seu conteúdo.
Uma string opaca, como um hash de senha
O formato proposto reutiliza a sintaxe PHC, conhecida por representar hashes de senha com algoritmo e parâmetros na mesma string. Um registro teria esta aparência:
$webauthn$v=1$transports=hybrid+internal$<dados-do-autenticador-em-base64>
O prefixo identifica WebAuthn e a versão do formato. O parâmetro opcional transports informa meios pelos quais o autenticador pode ser usado, como acesso interno ao dispositivo ou fluxo híbrido. O restante contém, em Base64 sem padding, os dados binários do autenticador já definidos pelo próprio WebAuthn.
Para o código de negócio, essa string seria opaca. A aplicação só precisaria associar um ou mais registros à conta correta, assim como hoje associa um hash de senha a um usuário. Uma biblioteca especializada receberia o registro para validar a resposta de autenticação ou excluir credenciais já cadastradas durante um novo registro.
O ganho principal é a interoperabilidade. Se bibliotecas diferentes adotarem o mesmo formato, uma equipe poderá trocar a implementação sem redesenhar a tabela de credenciais. Metadados de produto — apelido da passkey, data de criação e último uso — continuam em colunas normais, porque não fazem parte da verificação criptográfica.
Como seria a API crypto/passkey
Além do formato, Valsorda publicou um rascunho de API stateless para um possível pacote crypto/passkey. No cadastro, o backend chamaria algo como NewRegistration, enviaria as opções JSON ao navegador, receberia a credencial criada e usaria Register para produzir o registro opaco que será salvo.
No login, o fluxo seria dividido em etapas:
NewLogingeraria o desafio e as opções para o navegador.- A aplicação guardaria temporariamente a requisição em um cache com TTL curto.
Inspectextrairia da resposta os identificadores necessários para localizar desafio, usuário e registros.Loginverificaria a resposta contra o desafio e as passkeys daquela conta.
A aplicação ainda seria responsável por três tarefas importantes: manter um identificador permanente e não revelador para o usuário, persistir as passkeys vinculadas à conta e armazenar desafios de curta duração. A biblioteca cuidaria da codificação, parsing e validações WebAuthn mais delicadas.
Essa separação combina bem com aplicações Go: o pacote não precisaria controlar banco, sessão ou framework HTTP. Ele receberia e devolveria valores, deixando infraestrutura e política de conta sob responsabilidade do serviço. Para uma visão mais ampla dessa separação entre identidade, credencial e autorização, consulte nosso guia de autenticação e autorização em Go.
O que a proposta não resolve
O formato não transforma passkeys em um recurso simples de adicionar sem planejamento. Recuperação de conta, remoção de credenciais, múltiplos dispositivos, proteção dos desafios e experiência de fallback continuam sendo decisões do produto.
Há também campos mutáveis. O estado de backup pode mudar depois do cadastro e, caso a aplicação dependa desse sinal, precisa armazená-lo separadamente e atualizá-lo após o login. O contador de assinaturas é outro exemplo, embora o texto observe que ele é pouco usado em grandes implantações.
A proposta também evita um índice global por Credential ID. Em vez de aceitar um identificador fornecido pelo autenticador como chave primária, o fluxo localiza primeiro o usuário e verifica a credencial dentro do conjunto associado à conta. Segundo o autor, isso remove a classe de colisão introduzida pelo próprio índice global.
Mais importante: crypto/passkey ainda não existe. O autor está buscando feedback antes de eventualmente abrir uma proposta para Go 1.28. Portanto, o rascunho serve hoje para orientar discussão e desenho de APIs, não como dependência de produção ou promessa de inclusão na biblioteca padrão.
Por que vale acompanhar
Passkeys atacam phishing sem criar outro segredo compartilhado para o servidor proteger. Um formato comum de persistência pode fazer por WebAuthn algo semelhante ao que strings de hash fizeram por senhas: separar o registro armazenado da implementação usada para verificá-lo.
Para equipes Go, a proposta é especialmente interessante por buscar uma API pequena, stateless e independente de framework. Mesmo que o pacote final mude ou nunca entre na biblioteca padrão, a discussão ajuda a definir uma fronteira melhor entre autenticação criptográfica, persistência e regras da aplicação.