Pular para o conteúdo

Autenticação

Cada integrador recebe uma chave de API. Ela identifica um sistema, define quais estações ele enxerga e a qual cota ele está sujeito.

Envie a chave no cabeçalho X-Api-Key, em toda requisição:

Terminal window
curl https://api.radar-sandbox.kitelife.com.br/v1/stations \
-H "X-Api-Key: $RADAR_API_KEY"

O cabeçalho Authorization: Bearer <chave> também é aceito e vale exatamente o mesmo. Use o que for mais natural no seu cliente HTTP; muitos já trazem suporte a Bearer embutido, e nesses casos não faz sentido montar um cabeçalho à mão. Envie um ou outro, nunca os dois.

Chave ausente, inválida ou revogada devolve 401 com corpo ProblemDetails e code: ApiKey.NotRecognized. Uma chave válida pedindo uma estação fora do seu escopo devolve 404, não 403: do ponto de vista da sua credencial, aquela estação não existe, e responder 403 revelaria que ela existe para outra pessoa.

Depende de onde o cliente roda.

Qualquer cliente WebSocket de servidor controla os cabeçalhos do handshake, e aí a autenticação é igual à da REST: mande Authorization: Bearer <chave> ou X-Api-Key na abertura da conexão. Não é preciso mais nada.

// Node, biblioteca ws
new WebSocket('wss://stream.radar-sandbox.kitelife.com.br/v1/stream', {
headers: { Authorization: `Bearer ${process.env.RADAR_API_KEY}` },
})

Do navegador não dá, e a limitação não é nossa: a API WebSocket do navegador aceita apenas a URL e a lista de subprotocolos. Não existe forma de definir Authorization nem qualquer outro cabeçalho no handshake.

Sobra colocar a credencial na URL, e uma URL vaza com facilidade: fica no histórico, nos logs de qualquer proxy no caminho e no cabeçalho Referer. Por isso o handshake do navegador usa um ticket:

  1. Peça um ticket na REST, autenticando com a chave normalmente.
  2. Abra a conexão com wss://stream.radar-sandbox.kitelife.com.br/v1/stream?ticket=….

O ticket vale 60 segundos, serve para uma única conexão e herda o escopo da chave que o emitiu. Peça um novo a cada reconexão: reaproveitar o anterior falha com Ticket.Expired.

Vazado, um ticket vale quase nada. Vazada, uma chave vale tudo até ser revogada. É essa a diferença que o desenho compra.

Há quem passe o token pelo cabeçalho Sec-WebSocket-Protocol, que o navegador deixa preencher. Nós não aceitamos esse caminho: ele resolve o transporte e deixa o problema de fundo intacto, que é a chave de API estar dentro de um navegador.

O relay usa usuário e senha AMQP próprios, entregues no provisionamento da sua fila, sobre TLS na porta 5671. As credenciais dão permissão de consumo apenas, na sua fila: você não declara filas, não altera bindings e não publica.

A chave de API da REST não vale no broker, e vice-versa. São credenciais separadas de propósito: vazar uma não compromete a outra.

A chave é uma credencial de servidor. Embutida em aplicativo móvel, em página web ou em repositório público, ela é uma chave pública: qualquer pessoa extrai. Se o seu front-end precisa dos dados, o caminho é seu servidor buscar e repassar.

Precisando de acesso direto do navegador, fale conosco antes. O desenho para esse caso é outro, com credencial de escopo reduzido, e não é a sua chave de integrador.

Uma chave comprometida deve ser trocada, e a troca não exige janela de indisponibilidade: emitimos a nova credencial deixando a antiga válida, você migra, e só então revogamos a antiga.

O mesmo vale para o AMQP, com um par adicional de usuário e senha.

Peça a rotação antes de trocar a configuração, nunca durante: revogar primeiro derruba a sua integração até a nova chave estar no ar.