Docker lança GenAI Stack e AI Assistant na DockerCon
24 de janeiro de 2024Mais fácil, mais rápido e melhor: microsserviços em tempo real
24 de janeiro de 2024O componente de gateway de API em uma arquitetura nativa da nuvem é fundamental porque transfere a segurança crítica da API e a funcionalidade de política para um local comum, permitindo que as APIs e serviços de back-end se concentrem na lógica de negócios. Autenticação de API, autorização, auditoria, limitação e tarefas semelhantes podem ser complexas e difíceis de acertar, por isso muitas organizações escolhem um gateway de API para lidar com elas.
E quanto ao tráfego serviço a serviço (S2s) ou interno, leste/oeste? Forçar o tráfego S2S a voltar através do gateway de API cria saltos extras, mais latência, aumento de tráfego e diminuição de eficiência.
Mas como você pode proteger o tráfego se ignorar o gateway da API e chamar os serviços diretamente? Como o serviço do destinatário se autentica e sabe quem está ligando?
Duas maneiras comuns de proteger a comunicação S2S são:
- Usando Transport Layer Security (TLS) e certificados de cliente (TLS mútuo ou mTLS).
- Usando JSON Web Tokens (JWTs) assinados.
Uma malha de serviço resolve o problema usando a opção um para automatizar muitas práticas recomendadas e mitigar as desvantagens.
Os desenvolvedores podem optar por usar JWTs para autenticação S2S, mas isso “desvenda” o que você espera que o gateway API faça. Ou seja, toda a complexidade e fragilidade do tratamento da segurança que você transferiu para o gateway API deve ser recriada e reduplicada em cada microsserviço para comunicação S2S. Este é um grande problema porque o uso de JWTs para autenticação S2S traz complexidade e atenção aos detalhes. (Para saber mais sobre este tópico e os cenários abaixo, assista ao episódio 59 do Hoot: “JWT vs mTLS para autenticação serviço a serviço.” Todas as demonstrações estão disponíveis em nosso repositório GitHub.)
Embora existam ótimas estruturas e bibliotecas para lidar com JWTs, e embora o JWT tenha seu lugar, usar o JWT para autenticar o tráfego S2S é complexo, trabalhoso e coloca muita confiança nos desenvolvedores para fazer as coisas exatamente certas. Essa complexidade (ou falta de conhecimento) pode reduzir a postura geral de segurança se os desenvolvedores economizarem ou ignorarem propriedades cruciais. Os desenvolvedores também precisam fazer isso de uma maneira específica da linguagem e da estrutura (por exemplo, resolver isso em Java é diferente de Go ou Node.js). Manter, corrigir e auditar cada implementação em todas as bases de código é caro.
Solo.io, a moderna empresa de infraestrutura de API, oferece redes de aplicativos desde a borda até a malha de serviço, permitindo que as empresas adotem, protejam e operem tecnologias inovadoras nativas da nuvem.
Saber mais
As últimas novidades do Solo.io
$(document).ready(function() { $.ajax({ método: ‘POST’, url: ‘/no-cache/sponsors-rss-block/’, headers: { ‘Cache-Control’: ‘no- cache, no-store, must-revalidate’, ‘Pragma’: ‘no-cache’, ‘Expires’: ‘0’ }, dados: { patrocinadorSlug: ‘solo-io’, numItems: 3 }, sucesso: function( dados) { if (data.startsWith(‘ERROR’)) { console.log(data); $(‘.sponsor-note-rss’).hide(); } else { $(‘.sponsor-note-rss -items-solo-io’).html(dados); } } }); });
Como usar JWTs para autenticar a comunicação S2S
Existem duas abordagens para criar um JWT para autenticar a comunicação S2S: usar um provedor de identidade (IdP) (também conhecido como serviço de token seguro ou STS) ou permitir que serviços individuais autoassinem os JWTs. (Se você é novo ou precisa se atualizar sobre os conceitos de JWT, AuthO oferece uma boa visão geral dos JWTs.)
Opção 1: Use um STS para emitir tokens
A primeira abordagem usa um serviço de token seguro (STS), uma identidade confiável ou provedor de token, como Keycloak, Okta ou Auth0 para emitir tokens que representam um serviço específico.
Nessa abordagem, um serviço troca uma credencial de longo prazo (como nome de usuário e senha ou credenciais de cliente OAuth2.0) por um JWT do STS que diz “Eu sou o Serviço A”.
Observação: uma credencial de “longo prazo” deve ser armazenada de forma segura e usada de forma limitada. Por exemplo, você poderia usá-lo uma vez para inicializar a identidade na inicialização e nunca mais. Além disso, essas credenciais só devem ser armazenadas na memória.
O STS assina o JWT com sua chave privada, que pode ser verificada com sua chave pública. O Serviço A então anexa o JWT em uma solicitação ao Serviço B. A partir daqui, o Serviço B pode verificar se o JWT foi emitido pelo STS, verificando a assinatura do JWT usando a chave pública do STS.
Para que isso funcione:
- O tráfego deve ser criptografado.
- O serviço B deve verificar o
aud
reivindicação, expiração, emitida em e não antes das reivindicações do JWT. - O serviço B deve estar preparado para atualizar a chave pública STS quando ela for rotacionada.
Criptografar o tráfego é fundamental porque quando os JWTs são usados dessa maneira, eles representam um “token de portador”, para que qualquer pessoa com o token possa representar o Serviço A. Criptografar o tráfego (como com TLS de servidor unidirecional) entre o Serviço A e o Serviço B ajuda a mitigar isso.
O serviço B também deve verificar a expiração (exp
), emitido em (iat
), não antes do tempo (nbf
), e especialmente o aud
reivindicação para verificar se o token é válido (não expirou, dentro de sua janela de tempo e destinado ao uso pelo Serviço B). Os JWTs usam esta convenção para se proteger contra ataques de repetição em que um invasor se faz passar pelo Serviço B, pega o token do Serviço A e depois se faz passar pelo Serviço A para chamar o Serviço C. Um Serviço C válido verificaria o aud
reivindicação, consulte o JWT que representa o Serviço A destinado ao Serviço B – e rejeite-o.
Um JWT diferente deve ser usado para cada chamada de serviço A porque o aud
reivindicação será diferente. Tentando usar um JWT sem um aud
reivindicar ou usar um curinga aud
reivindicação aumenta o risco de um JWT comprometido. Evite fazer isso.
Por último, e muitas vezes ignorado, está a rotação das chaves públicas STS. No caso de rotação programada ou revogação planejada das chaves que o STS usa para assinar JWTs, o Serviço B (ou qualquer serviço que dependa do STS para verificação) deve ser capaz de lidar com chaves públicas de assinatura atualizadas.
Opção 2: faça com que o serviço assine seus próprios tokens
A segunda abordagem usa chaves específicas do serviço para assinar JWTs. Você pode usar chaves simétricas ou chaves assimétricas.
Nesse caso, o Serviço A usa suas próprias chaves para assinar os JWTs que envia ao Serviço B (ou qualquer outro serviço). O Serviço B precisará da chave pública do Serviço A (ou chave simétrica, que é mais perigosa devido a questões de troca de chaves e representação) para verificar os envios do Serviço JWT A. Na verdade, o Serviço B precisará de todas as chaves públicas para qualquer serviço que o chame usando JWTs como princípios de autenticação.
Como no exemplo do JWT emitido pelo STS, o tráfego entre os serviços deve ser criptografado, o Serviço B também deve verificar o aud
reivindicação, e você precisa de uma maneira de assinar a rotação de chave pública. Você também deve usar um JWT diferente para cada serviço chamado.
Os desenvolvedores devem implementar e monitorar muitas coisas para acertar. Os certificados também devem ser emitidos para pelo menos metade dos serviços (os serviços na extremidade receptora) para, no mínimo, fornecer TLS unidirecional. Além disso, a chave para todo o processo é o gerenciamento de chaves, a rotação e a guarda de segredos.
Onde as coisas podem dar errado com o JWT
Abordamos algumas maneiras pelas quais os JWTs podem ser usados para representar a identidade do serviço e sugestões de áreas de preocupação. Há diversas áreas que devem ser observadas de perto em sua arquitetura de serviços para evitar falhas de segurança. Se não forem à prova de balas, você dará aos invasores oportunidades de comprometer seu sistema.
Uma das diferenças mais importantes entre o uso de certificados de cliente/mTLS, como faz uma malha de serviço, e JWTs para autenticação é esta: os JWTs enviam o material do token de portador sensível pela rede, enquanto os mTLSs não. Com o mTLS, apenas a chave pública é enviada pela rede, não a chave privada, e as chaves de sessão são negociadas. Se o JWT vazar, o JWT será o material secreto privado e poderá ser reproduzido. Com certificados, apenas os certificados públicos são compartilhados pela rede.
Para evitar a repetição do token ao portador, você deve limitar a exposição definindo breves tempos de expiração, de preferência apenas alguns minutos. Isso coloca mais responsabilidade sobre os serviços para atualizar seus JWTs para suas solicitações. Definir a expiração para horas, dias ou meses acontece com muita frequência. Esta é uma grande falha de segurança.
Outra grande lacuna de segurança é que, ao usar um STS para obter o material JWT, você envia as credenciais de longa duração (por exemplo, para um fluxo client_credentials) pela rede inúmeras vezes. Essas credenciais de longa duração são extremamente confidenciais e devem ser usadas com moderação (por exemplo, na inicialização), e não continuamente.
Além disso, usando curinga aud
reivindicações ou sair aud
desligar completamente é outro grande problema. Deixar de usar essas convenções de forma consistente entre os serviços para autenticação abre problemas significativos. Certifique-se de criar JWTs com os corretos aud
reivindicação por cada serviço chamado.
Por último, a rotação de chaves é tão importante quanto a expiração curta e aud
verificações de reclamação. A invalidação de chaves é um último esforço para revogar JWTs no caso de uma violação e deve ser tratada da forma mais rápida e eficiente possível.
A complexidade do JWT é onde o Service Mesh simplifica as coisas
Uma malha de serviço simplifica a autenticação serviço a serviço e permite que os desenvolvedores se concentrem em sua lógica de negócios, sem discutir JWTs e material secreto (espero) corretamente. Assim como um gateway de API deve ser usado para lidar com a segurança do tráfego norte/sul e de entrada, uma malha de serviço deve ser usada para o tráfego leste/oeste e S2S. Mantenha os serviços e APIs focados no valor comercial diferenciador que eles podem oferecer, e não no código de segurança padronizado (mas extremamente importante).
Para um mergulho mais profundo, assista ao nosso tutorial no YouTube ou leia um artigo de nossos colegas Lin Sun e Yuval Kohavi escrevi recentemente sobre o uso de mTLS para resolver a autenticação S2S. Você também pode acessar o repositório GitHub que mostra esses cenários e como implementar a autenticação S2S usando a malha de serviço do Istio. A documentação desse repositório GitHub mostra em detalhes dolorosos como é difícil acertar.
A postagem Usando JWTs para autenticar serviços desvenda gateways de API apareceu pela primeira vez em The New Stack.