@xdevplatform/chat-xdk). As chaves privadas de identidade e de assinatura ficam no dispositivo do usuário. Seus servidores (e o X) só enxergam texto cifrado, chaves públicas e tokens OAuth — nunca o PIN nem o material de chave privada usado para criptografar e assinar mensagens.
Esta página é a arquitetura recomendada para apps cliente. Para regras de PIN e manuseio de chaves aplicáveis a todo tipo de app, veja Gerenciamento de chaves privadas.
Por que WASM para apps de UI
Usuários finais nunca devem colar o PIN de criptografia no seu backend, e seu backend nunca deve manter as chaves privadas de identidade deles. Se um servidor de terceiros recebe o PIN ou as chaves privadas raiz do usuário, essa parte consegue descriptografar as chaves de conversa envelopadas para aquela identidade mesmo depois que o usuário revoga o acesso OAuth. O WASM no cliente evita essa classe de falha para apps legítimos.
Arquitetura recomendada
Separe criptografia (navegador) do transporte da API (seu backend ou a X API diretamente com um token de usuário):
Um padrão comum (usado por demos internos, como clientes de chat no navegador) é: WASM + React (ou similar) no frontend, XDK em TypeScript nas rotas de API do Next.js (ou outro) para que o navegador nunca converse com
api.x.com usando um segredo de longa duração, se você preferir evitar isso. A criptografia continua rodando apenas no navegador.
Instale o pacote para navegador
@xdevplatform/chat-xdk; não há uma toolchain Rust separada para os consumidores. Requer um navegador moderno (e Node.js 18+ se você compartilha código com SSR — rode a criptografia apenas no cliente).
Fluxo de sessão (PIN uma vez, chaves permanecem em memória)
Não peça o PIN a cada mensagem. Desbloqueie uma vez por sessão do navegador, mantenha a instânciaChat em memória (singleton de módulo, contexto React, etc.) e depois criptografe e descriptografe usando essa instância desbloqueada.
Expectativas de UX
O que seu servidor pode ver
Tokens de realm para o Juicebox não são o PIN do usuário. Eles autorizam o protocolo de backup para aquele usuário e versão de chave. Continue emitindo-os em um backend que já mantém o contexto OAuth do usuário.
Backup seguro de chaves no navegador
Apps cliente devem usar backup seguro de chaves (setup / unlock com um código de acesso), não um arquivo de chave em bruto:
- Carregue
juicebox_configdo registro de chave pública do usuário (public_key.fields=juicebox_config). createChat({ juiceboxConfig, getAuthToken }).- Na primeira vez:
generateKeypairs→ registre as chaves públicas com o X →setup(pin). - Depois:
unlock(pin)neste dispositivo (ou em um novo dispositivo com o mesmo PIN).
createChat, então o JavaScript da aplicação não é incentivado a puxar bytes de chave raiz para dentro da página. Prefira esse modelo a despejos manuais de chave em localStorage.
Passos completos de registro e unlock: Guia de introdução. Conceitos: Primer de criptografia.
Checklist de hardening no navegador
- Rode o Chat XDK apenas em bundles de cliente (sem SSR de chaves desbloqueadas).
- Trate a instância
Chatdesbloqueada como um segredo de sessão vivo: não a coloque emwindow, não a registre em log, não a envie para analytics. - Defenda-se contra XSS: CSP, uso cuidadoso de
dangerouslySetInnerHTML/ renderização de markdown, higiene de dependências. Um XSS em um app de chat consegue alcançar chaves em memória mesmo quando as chaves nunca vão para a rede. - Use HTTPS em todo lugar; nunca misture páginas com criptografia e scripts inseguros.
- Prefira escopos OAuth mínimos; solicite escopos de DM apenas quando necessário e explique-os na UI do seu produto.
- No logout, chame
lock()/free()e descarte a instância.
localStorage, como pensar sobre persistência de sessão) estão em Gerenciamento de chaves privadas.
Próximos passos
- Gerenciamento de chaves privadas — avisos sobre PIN, armazenamento, bots vs apps de UI
- Guia de introdução — registro completo de chaves e primeira mensagem
- Chat XDK — referência da API para
createChat, encrypt, decrypt - Eventos em tempo real — entrega de texto cifrado ao cliente para descriptografia local