cord login sem copiar chaves, e um assistente que integra o Cord por você

Como construímos o fluxo de dispositivo do CLI do Cord, por que o terminal recebe uma chave restrita de uso único e o que faz o assistente do npx @flouviahq/cli.

O primeiro contato com uma plataforma de pagamentos costuma ser o pior: entrar no painel, encontrar a seção de chaves, copiar uma sequência de 50 caracteres, colá-la em um .env e torcer para não tê-la enviado ao GitHub. Queríamos que, com o Cord, bastasse um comando:

npx @flouviahq/cli

O fluxo de dispositivo

cord login usa o mesmo padrão da televisão quando ela pede que você entre pelo celular (o fluxo de dispositivo da RFC 8628):

  1. O terminal pede um código a POST /api/cli/login. O Cord gera duas coisas: um device code de 32 bytes aleatórios que só o terminal conhece e um user code curto, como WXYZ-2346, para você ver.
  2. O terminal abre seu navegador em /app/cli/autorizar?codigo=WXYZ-2346. Lá, com sua sessão normal do Cord, você confirma que o código é o mesmo que aparece no terminal e clica em Autorizar.
  3. Enquanto isso, o terminal consulta POST /api/cli/login/claim a cada dois segundos com seu device code. Assim que você aprova, ele recebe a chave.

Algumas decisões que não são óbvias:

  • No banco de dados fica apenas o sha256 do device code. Quem lesse a tabela não conseguiria reivindicar nada.
  • O user code não usa caracteres que se confundem ao serem ditados (0 e O, 1, I e L, 5 e S). São 8 caracteres de um alfabeto de 25.
  • A tabela não tem políticas de acesso. Ela tem segurança em nível de linha forçada e nenhuma política, então nenhuma consulta direta a enxerga. Só é acessada por quatro funções security definer restritas: criar, buscar, decidir e reivindicar.
  • A chave é entregue uma única vez. Ela fica guardada criptografada até que o terminal a reivindique; nesse momento, o registro passa a reclamado e o segredo é apagado. O código expira em 10 minutos.
  • O terminal só abre no navegador um endereço da mesma origem que a API. O servidor não decide para qual site enviar você.

Uma chave que não pode causar danos

O terminal não recebe uma chave de administrador. Recebe uma chave restrita de teste (rk_test_) com três permissões: usar os simuladores, ler eventos e propor configurações. Ela expira em 90 dias e aparece no painel de API como CLI · <sua máquina>, onde você pode revogá-la.

As chaves restritas do Cord têm um nível por recurso, derivado da rota. Uma rota nova da API nasce proibida para elas até que alguém decida a qual recurso ela pertence, e um teste falha se uma rota ficar sem recurso.

Como as chaves de teste contam para o limite do plano, reconectar a mesma máquina revoga a chave anterior dessa máquina. Um terminal, uma chave.

Uma única autorização para tudo

Seu projeto também precisa de uma chave para que o servidor dele se comunique com o Cord. Quando o assistente vai integrar um projeto, a tela de autorização mostra mais uma caixa de seleção: “Criar também uma chave para este projeto”. Se você a deixar marcada, o Cord cria uma Secret Key de teste, criptografa-a junto com a do CLI e entrega as duas juntas uma única vez. O assistente a grava no seu .env.local.

Se o seu plano já não tiver espaço para outra chave, o CLI fica conectado mesmo assim e a página avisa você; nada fica quebrado pela metade.

O assistente

Sem comando, o CLI abre um assistente com menus, indicadores de progresso e um resumo final. Passo a passo:

  1. Conecta o terminal com o fluxo acima.
  2. Pergunta o que fazer: configurar a conta com IA, integrar o projeto e testar webhooks.
  3. Configura sua conta: lê seu site e sua lista de preços, mostra a proposta e espera que você a aprove no navegador.
  4. Integra o projeto: detecta o framework (Next.js, Astro, Express, Laravel, Django, Flask ou FastAPI), mostra exatamente o que vai fazer e, se você aceitar, instala o SDK com seu gerenciador de pacotes e cria duas rotas: a que verifica a assinatura de cada webhook e um proxy para o Cord Elements.
  5. Escuta webhooks: abre uma sessão de teste, salva o segredo dela no seu .env.local e reencaminha cada evento para o seu servidor local.

Três regras que o assistente nunca quebra:

  • Não sobrescreve arquivos. Se a rota já existir, ele a mantém e avisa você.
  • Só grava chaves em um arquivo de ambiente que o git ignora. Se não encontrar um, não grava nada e informa qual variável adicionar.
  • Não mexe nas outras linhas do seu .env. Só atualiza ou adiciona as variáveis do Cord.
◆  Esto es lo que voy a hacer
│  +  instalar    @flouviahq/node @flouviahq/elements  · con npm
│  +  crear       app/api/webhooks/cord/route.ts       · verifica la firma de cada webhook
│  +  crear       app/api/cord/[...path]/route.ts      · proxy seguro para Cord Elements
│  ~  escribir    .env.local                           · CORD_SECRET_KEY de prueba

Sem dependências

A interface usa @clack/prompts, mas o pacote publicado não depende de nada: o esbuild o empacota com todo o resto em um único arquivo na compilação. Instalar o CLI não traz uma nova árvore de dependências para a sua máquina.

Experimente

npx create-next-app@latest my-store --ts --app
cd my-store
npx @flouviahq/cli

Ao terminar, rode npm run dev em um terminal e npx @flouviahq/cli trigger quote.approved em outro: o evento chega à sua rota, assinado, e o terminal mostra o 200.