Home > Blog > Desenvolvimento Web
Desenvolvimento Web
JavaScript
Programação

mTLS no Node.js: Guia Prático

Atualizado em: 31 de agosto de 2026

Rack de servidores processando fluxos de dados no Node.js

Implementar mTLS no Node.js permite que servidor e cliente apresentem certificados durante o handshake TLS. No HTTPS tradicional, o cliente valida o certificado do servidor. No mutual TLS, o servidor também valida o certificado do cliente, criando autenticação criptográfica nos dois sentidos.

mTLS é útil em comunicação entre serviços, integrações B2B, APIs administrativas e ambientes com requisitos de identidade de workload. A tecnologia não substitui autorização: um certificado válido identifica o cliente, mas a aplicação ainda precisa decidir quais rotas, tenants e ações estão permitidos.

Neste guia, você aprenderá a criar um servidor HTTPS com certificado cliente obrigatório, configurar o cliente, validar CA, ler o certificado, mapear identidades, rotacionar chaves, usar proxies, revogar acesso, monitorar e testar o fluxo.

O que é mTLS?

mTLS significa Mutual Transport Layer Security. O módulo nativo node:tls fornece a implementação TLS do Node.js sobre OpenSSL. A RFC 8446 define TLS 1.3.

TLS comum versus mTLS

  • TLS comum: cliente valida o servidor.
  • mTLS: cliente valida o servidor e servidor valida o cliente.

O canal fica cifrado nos dois casos. A diferença é a autenticação do cliente por certificado.

Componentes

  • CA raiz ou intermediária;
  • certificado do servidor;
  • chave privada do servidor;
  • certificado do cliente;
  • chave privada do cliente;
  • política de emissão e rotação;
  • mapeamento entre certificado e identidade.

Autoridade certificadora

A CA assina certificados confiáveis. Em ambientes internos, use uma PKI própria ou serviço gerenciado. Não compartilhe a chave privada da CA com aplicações.

Certificados autoassinados

Um certificado autoassinado isolado pode funcionar em desenvolvimento, mas não escala bem para rotação e revogação. Prefira uma CA que assine certificados individuais.

Servidor HTTPS com mTLS

import https from 'node:https';
import fs from 'node:fs';

const server = https.createServer({
  key: fs.readFileSync('/run/tls/server-key.pem'),
  cert: fs.readFileSync('/run/tls/server-cert.pem'),
  ca: fs.readFileSync('/run/tls/client-ca.pem'),
  requestCert: true,
  rejectUnauthorized: true,
  minVersion: 'TLSv1.2'
}, app);

server.listen(8443);

requestCert solicita o certificado do cliente. rejectUnauthorized rejeita conexões que não passam pela validação da CA.

Não use rejectUnauthorized false

rejectUnauthorized: false

Essa configuração aceita certificados não confiáveis e elimina a principal proteção. Não use como correção para erros de cadeia.

Cliente HTTPS

import https from 'node:https';
import fs from 'node:fs';

const agent = new https.Agent({
  key: fs.readFileSync('/run/tls/client-key.pem'),
  cert: fs.readFileSync('/run/tls/client-cert.pem'),
  ca: fs.readFileSync('/run/tls/server-ca.pem'),
  minVersion: 'TLSv1.2',
  keepAlive: true
});

O cliente envia seu certificado e valida o servidor com a CA configurada.

Fetch com agente

O mecanismo exato depende do cliente HTTP. Bibliotecas como Undici permitem configurar um dispatcher com opções TLS. Confira a documentação da versão usada.

Hostname do servidor

O certificado do servidor precisa conter o hostname em Subject Alternative Name. Não desabilite a validação de hostname.

Certificate Authority

O campo ca deve conter a cadeia confiável apropriada. Não confie em certificados individuais de clientes quando uma CA e política de emissão são mais adequadas.

Lendo o certificado do cliente

app.use((req, res, next) => {
  if (!req.socket.authorized) {
    return res.status(401).end();
  }

  const certificate = req.socket.getPeerCertificate();
  req.clientCertificate = certificate;
  next();
});

authorized e authorizationError

authorized indica se a cadeia foi validada. Quando falha, authorizationError ajuda no diagnóstico interno. Não envie detalhes do certificado ao cliente.

Identidade no certificado

Você pode usar Subject Alternative Name, URI, DNS ou outro identificador emitido pela CA. Evite depender apenas de Common Name em desenhos modernos.

URI de workload

spiffe://empresa.local/ns/payments/sa/api

Identidades URI facilitam mapear workload e ambiente, especialmente com SPIFFE e service mesh.

Mapeando para o cliente

const identity = extractApprovedIdentity(certificate);
const client = await clients.findByCertificateIdentity(identity);

if (!client || client.status !== 'active') {
  throw new UnauthorizedError();
}

O certificado válido precisa corresponder a um registro ativo.

Autenticação não é autorização

Depois de identificar o cliente, verifique escopos e recursos:

requirePermission(client, 'payments.read');

Consulte RBAC no Node.js e ABAC no Node.js.

mTLS e API keys

Uma integração pode combinar certificado com API key. O certificado identifica a máquina ou organização; a chave representa uma credencial adicional com escopos.

Veja API Keys no Node.js.

mTLS e OAuth

Arquiteturas OAuth podem vincular tokens ao certificado, reduzindo uso por quem rouba apenas o token. A configuração é mais complexa e deve seguir o provedor e as especificações adotadas.

Certificado por serviço

Não compartilhe o mesmo certificado entre todos os serviços. Credenciais individuais permitem revogar, auditar e aplicar políticas específicas.

Certificado por ambiente

Desenvolvimento, homologação e produção devem usar CAs ou políticas distintas. Um certificado de teste não deve autenticar produção.

Chave privada

A chave privada é um segredo. Armazene em Secret, KMS, HSM, volume protegido ou identidade de workload.

Consulte Gestão de Segredos no Node.js.

Permissões do arquivo

chmod 600 client-key.pem

O processo deve ser o único usuário autorizado a ler a chave.

Passphrase

Chaves podem ser cifradas com passphrase, mas o processo precisa receber essa passphrase. Em serviços automatizados, HSM ou secret mount pode ser mais prático.

Rotação de certificado

  1. Emitir certificado novo.
  2. Entregar ao workload.
  3. Recarregar sem interromper conexões novas.
  4. Confirmar uso.
  5. Revogar ou expirar o antigo.
  6. Auditar.

Sobreposição

Durante a rotação, a CA pode aceitar certificado antigo e novo por um período curto. Isso evita indisponibilidade.

Recarregando contexto

Servidores Node.js podem atualizar o contexto TLS ou reiniciar de forma gradual. Teste o comportamento do framework e do balanceador.

Conexões existentes

Rotacionar certificado afeta novos handshakes. Conexões keep-alive já estabelecidas podem continuar até serem drenadas.

Expiração curta

Certificados de workload com validade curta reduzem a dependência de listas de revogação e limitam o impacto de vazamento.

Renovação automática

Use um agente ou plataforma que renove antes do vencimento. Monitore o prazo e alerte com antecedência.

Revogação

CRL e OCSP podem ser usados conforme a PKI. Em ambientes internos, certificados curtos e remoção da identidade no gateway também são comuns.

Serial number

Registre serial, issuer e fingerprint para auditoria. Não use apenas o subject, que pode ser repetido.

Fingerprint

Pinning por fingerprint facilita um caso pequeno, mas torna rotação difícil. Uma CA com identidade e política geralmente escala melhor.

Proxy reverso

O mTLS pode terminar no Nginx, load balancer ou API Gateway. Nesse caso, o proxy valida o certificado e encaminha uma identidade confiável.

Headers internos

Remova headers fornecidos pelo cliente e defina novos valores somente no proxy:

X-Client-Certificate-Identity
X-Client-Certificate-Serial

A aplicação deve aceitar esses headers apenas de proxies autenticados.

mTLS fim a fim

Quando o risco exige, mantenha TLS mútuo entre proxy e serviço, em vez de confiar apenas na rede interna.

API Gateway

Gateways podem centralizar certificados, políticas e rate limiting. Consulte API Gateway no Node.js.

Service mesh

Uma malha pode emitir certificados de workload e aplicar mTLS transparente. Ainda é necessário validar autorização e política de tráfego.

Zero Trust

mTLS fornece identidade de conexão, mas Zero Trust também exige autorização, estado do dispositivo, segmentação, observabilidade e privilégio mínimo.

TLS mínimo

Use versões modernas e evite reduzir o nível de segurança apenas para clientes antigos. A documentação do Node.js recomenda cautela ao alterar suites e níveis padrão.

Ciphers

Os defaults do Node.js refletem práticas atuais. Personalizar suites sem necessidade pode remover proteções. Faça apenas com requisito e teste.

Session resumption

Reuso de sessão reduz custo de handshake. As chaves de ticket são segredos e precisam de rotação e distribuição segura entre instâncias.

Keep-alive

Clientes devem reutilizar conexões para reduzir CPU e latência. Consulte HTTP Agent no Node.js.

Timeouts

Defina timeout de handshake, conexão e resposta. Clientes que abrem sockets sem completar TLS podem consumir recursos.

Rate limiting

Certificado válido não autoriza tráfego ilimitado. Limite por identidade e rota.

Logs

Registre identidade, serial, issuer, protocolo, cipher, rota e resultado. Não registre a chave privada ou certificado completo sem necessidade.

Consulte Logs com Pino no Node.js.

Auditoria

Emissão, renovação, revogação e alterações de CA devem ser auditadas. Veja Logs de Auditoria no Node.js.

Métricas

Monitore handshakes, falhas por CA, certificados expirados, protocolo, latência, conexões reutilizadas e identidades bloqueadas.

Alertas

Alerte sobre certificado perto do vencimento, issuer inesperado, aumento de falhas e uso de identidade revogada.

Teste com OpenSSL

openssl s_client \
  -connect localhost:8443 \
  -cert client-cert.pem \
  -key client-key.pem \
  -CAfile server-ca.pem

Teste sem certificado

A conexão deve falhar antes da rota protegida.

Teste com CA errada

Um certificado assinado por CA não confiável deve ser rejeitado.

Teste de expiração

Use fixture expirada e confirme o erro. Monitore o código de validação internamente.

Teste de identidade

Um certificado válido para o serviço A não deve acessar permissões do serviço B.

Teste de rotação

Mantenha conexões ativas, instale o certificado novo e confirme que novas conexões usam a nova versão sem downtime.

Teste de proxy

Envie um header de identidade diretamente. O proxy deve removê-lo e a aplicação não deve confiar em origem externa.

Erros comuns

  • rejectUnauthorized false: certificados não confiáveis são aceitos.
  • Certificado compartilhado: não há identidade individual.
  • Common Name sem política: mapeamento fica frágil.
  • Chave na imagem: qualquer cópia possui a credencial.
  • Sem rotação: certificados expiram ou permanecem vazados.
  • Confiar em header externo: identidade é forjada.
  • Tratar mTLS como autorização: cliente recebe acesso excessivo.

Boas práticas

  • Use CA controlada.
  • Exija certificado cliente.
  • Mantenha rejectUnauthorized ativo.
  • Use identidade estável no SAN.
  • Emita certificado por workload.
  • Proteja chaves privadas.
  • Use validade curta.
  • Rotacione automaticamente.
  • Autorize por escopo.
  • Teste expiração e proxy.

Conclusão

Implementar mTLS no Node.js fornece identidade criptográfica para cliente e servidor durante o handshake. Isso protege integrações e comunicação entre serviços contra clientes sem certificado confiável.

O valor real aparece quando certificados são individuais, curtos e rotacionados, enquanto a aplicação aplica autorização por identidade e escopo. Com PKI, gerenciamento de segredos, observabilidade e testes de renovação, mTLS se torna uma camada forte sem criar certificados permanentes impossíveis de operar.

10 melhores cursos de programação em 2026

Descubra os melhores cursos de programação. Aprenda a escolher o curso ideal para iniciar ou avançar na carreira de desenvolvedor

POSTS RELACIONADOS

Ver todos

Seta para a direita