TLS (Transport Layer Security) é o protocolo que protege virtualmente toda comunicação de rede segura — HTTPS, SMTPS, banco de dados com SSL, gRPC, e praticamente qualquer protocolo moderno que exija confidencialidade e integridade em trânsito. Seu antecessor SSL (Secure Sockets Layer) foi desenvolvido pela Netscape em 1995; SSL 3.0 foi formalmente depreciado pelo NIST em 2015 após a descoberta do POODLE attack. TLS 1.0 e 1.1 foram depreciados em 2021 pelo RFC 8996. TLS 1.2 ainda é amplamente suportado mas tem limitações que o TLS 1.3 resolve. TLS 1.3, especificado na RFC 8446 em 2018, é o padrão atual e o mínimo que novos sistemas devem usar.
Entender TLS em profundidade — não apenas "habilitar HTTPS" mas compreender o handshake, o que os certificados verificam, e o que pode dar errado — é necessário para tomar decisões de configuração corretas. A diferença entre TLS 1.2 bem configurado e TLS 1.3 padrão envolve escolhas de cipher suites, forward secrecy, e latência de handshake. A diferença entre HSTS com preloading e sem envolve a janela de vulnerabilidade a MITM no primeiro acesso. Estas são decisões de engenharia com consequências de segurança, não knobs de configuração arbitrários.
O handshake TLS 1.3 — o que acontece antes do primeiro byte de dados
TLS 1.3 simplificou drasticamente o handshake em relação ao TLS 1.2. Enquanto TLS 1.2 requeria 2 round-trips antes de dados poderem ser transmitidos (TLS 1.2 full handshake: ClientHello → ServerHello/Certificate/ServerHelloDone → ClientKeyExchange/ChangeCipherSpec/Finished → ChangeCipherSpec/Finished), TLS 1.3 reduz para 1 round-trip:
Cliente Servidor
| |
|--- ClientHello -------------------------→ |
| - TLS version: 1.3 |
| - Random (32 bytes) |
| - Supported cipher suites |
| (TLS_AES_128_GCM_SHA256, |
| TLS_AES_256_GCM_SHA384, |
| TLS_CHACHA20_POLY1305_SHA256) |
| - Supported groups (key_share) |
| + Client's key share (ECDH public) |
| - Extensions (SNI, ALPN, etc.) |
| |
|← ServerHello + EncryptedExtensions ------ |
| + Certificate + CertificateVerify |
| + Finished (tudo criptografado já) |
| - Server's ECDH public key |
| - Encrypted certificate chain |
| - Signature sobre o handshake |
| |
|--- Finished (1 RTT total) -----------→ |
| - Client Finished (MAC) |
| |
|⟺ Application Data (ambos os lados) ⟺ |
O avanço principal é que o cliente envia sua parte do key exchange (ECDH public key) junto com o ClientHello — sem esperar a resposta do servidor. Isso permite que o servidor derive as chaves de sessão imediatamente ao receber o ClientHello, e retorne os dados do servidor (incluindo o certificado, já criptografado) em um único round-trip. O 0-RTT mode (TLS 1.3 Early Data) permite que o cliente envie dados da aplicação no primeiro pacote usando uma chave derivada de sessões anteriores — útil para APIs com muitas conexões de curta duração, mas com custo de segurança (suscetível a replay attacks se mal implementado).
Certificados X.509 — o que eles verificam e o que não verificam
Um certificado X.509 é um documento assinado digitalmente que associa uma chave pública a uma identidade. Quando seu browser conecta a bank.com, o servidor apresenta um certificado que afirma: "esta chave pública pertence a bank.com" — e a afirmação é assinada por uma Certificate Authority (CA) que o browser confia. O browser verifica a assinatura da CA, o que verifica indiretamente que a chave pública no certificado realmente pertence a bank.com.
O que o certificado X.509 contém:
Certificate:
Version: 3 (TLS 1.3 usa apenas v3)
Serial Number: 04:XX:XX:XX:XX
Signature Algorithm: ecdsa-with-SHA384
Issuer: Let's Encrypt ISRG Root X2
Validity:
Not Before: Jan 1 00:00:00 2024 GMT
Not After: Apr 1 00:00:00 2024 GMT # 90 dias — padrão Let's Encrypt
Subject: CN=bank.com
Subject Alternative Names:
DNS: bank.com
DNS: www.bank.com
DNS: api.bank.com
Public Key: EC (P-384)
Key Usage: Digital Signature
Extended Key Usage: TLS Web Server Authentication
O campo crítico é o Subject Alternative Name (SAN) — não o Common Name (CN). Desde 2000 (RFC 2818), a validação de hostname deve verificar o SAN; o CN é legado e muitos clientes modernos ignoram o CN se o SAN estiver presente. Um certificado wildcard *.bank.com cobre subdomains de um nível (api.bank.com) mas não múltiplos níveis (v1.api.bank.com).
O que o certificado não verifica: que o dono do domínio é quem você pensa que é, que a organização é legítima, ou que o site não é malicioso. Domain Validation (DV) — o tipo mais comum, usado pelo Let's Encrypt — verifica apenas que quem solicitou o certificado controla o domínio. Organization Validation (OV) e Extended Validation (EV) adicionam verificação de identidade organizacional, mas o suporte a EV nos browsers foi reduzido significativamente após pesquisas mostrarem que usuários não distinguem visualmente DV de EV.
Cadeia de certificados e trust anchors
A validação de um certificado segue uma cadeia: o certificado do servidor é assinado por um CA intermediário; o CA intermediário é assinado por um CA raiz; o CA raiz é pre-instalado no browser ou no sistema operacional como trust anchor. A validação percorre a cadeia de baixo para cima até encontrar um trust anchor.
O servidor deve enviar toda a cadeia (exceto o CA raiz, que o cliente já tem). Enviar apenas o certificado leaf e deixar o cliente resolver os intermediários via AIA (Authority Information Access) é uma fonte comum de erros de validação em clientes que não fazem o fetch automático dos intermediários — como curl, bibliotecas HTTP em linguagens de servidor, e alguns SDKs mobile.
Certificado que funciona no browser mas falha em clientes de API. O browser faz fetch automático de certificados intermediários via AIA; a maioria dos clientes HTTP em código não faz. O servidor deve enviar a cadeia completa (leaf + intermediário). Use openssl s_client -connect host:443 -showcerts para verificar o que o servidor está enviando — se só aparecer um certificado, a cadeia está incompleta.
Let's Encrypt e o protocolo ACME
Let's Encrypt, lançado em 2015 pelo Internet Security Research Group (ISRG), transformou a adoção de HTTPS ao tornar os certificados DV gratuitos e com emissão e renovação automatizadas. O protocolo subjacente é ACME (Automatic Certificate Management Environment, RFC 8555) — um protocolo JSON sobre HTTPS que permite que clientes ACME (Certbot, acme.sh, Let's Encrypt libraries) provem controle de domínio e obtenham certificados sem intervenção manual.
O challenge mais comum é HTTP-01: o servidor ACME coloca um token em http://dominio/.well-known/acme-challenge/TOKEN; o Let's Encrypt verifica que consegue acessar esse token pelo IP do domínio. Alternativas: DNS-01 (criar um registro TXT no DNS — necessário para wildcards e para domínios sem servidor HTTP acessível publicamente), e TLS-ALPN-01 (via extensão ALPN do TLS, para situações sem acesso HTTP).
// Configuração automática com Caddy — zero-config HTTPS com Let's Encrypt
// Caddyfile
bank.com {
reverse_proxy localhost:8080
# Caddy obtém e renova certificados automaticamente
# sem configuração adicional — ACME integrado
}
# Verificar renovação automática
# sudo systemctl status caddy
# caddy certificates # lista certificados gerenciados
Certificados Let's Encrypt têm validade de 90 dias — significativamente menor que os 1-2 anos dos certificados DV tradicionais. Isso foi uma decisão deliberada: renovações frequentes reduzem a janela de dano de um certificado comprometido e forçam automação (ninguém quer renovar certificados manualmente a cada 3 meses). A automação com Certbot (certbot renew --deploy-hook "systemctl reload nginx") ou com Caddy/Traefik que gerenciam ACME nativamente é o padrão.
HSTS — HTTP Strict Transport Security
HSTS (RFC 6797) instrui o browser a nunca fazer requisições HTTP ao domínio — apenas HTTPS — por um período especificado. Sem HSTS, a primeira visita a um site pode ser interceptada se o usuário digitar apenas bank.com (sem https://): o browser faz uma requisição HTTP que um MITM pode interceptar e responder antes do redirect 301 para HTTPS.
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
max-age: quantos segundos o browser deve lembrar de usar apenas HTTPS. 31536000 = 1 ano. Começar com valor pequeno (300) para testar, depois aumentar.includeSubDomains: aplica a todos os subdomains. Cuidado: se qualquer subdomain não suportar HTTPS, o acesso quebra.preload: solicita inclusão na lista HSTS preload (hstspreload.org). Browsers (Chrome, Firefox, Safari) incluem a lista em suas releases — o domínio nunca é acessível via HTTP, mesmo na primeira visita. Irreversível no curto prazo: remover da lista leva meses para propagar para todos os usuários.
A sequência correta para habilitar HSTS: (1) garantir que todo endpoint do domínio e subdomains suporta HTTPS; (2) habilitar HSTS com max-age pequeno e monitorar erros; (3) aumentar max-age gradualmente (1 semana, 1 mês, 1 ano); (4) adicionar includeSubDomains quando todos os subdomains estiverem prontos; (5) submeter para preload apenas quando o domínio for estável e a política for permanente. Submeter para preload prematuramente e depois descobrir que um subdomain não tem certificado bloqueia usuários.
Certificate Transparency — CT logs e como detectar certificados não autorizados
Certificate Transparency (RFC 6962) resolve o problema de CAs emitindo certificados para domínios sem autorização do dono. No CT, cada CA deve registrar todo certificado emitido em logs públicos e imutáveis (Merkle trees). Browsers verificam que o certificado apresentado aparece em pelo menos dois CT logs — certificados sem entrada em CT logs são rejeitados. Isso torna impossível uma CA emitir certificados silenciosamente sem que o dono do domínio possa detectar.
O serviço crt.sh (Certificate Transparency search) permite buscar todos os certificados emitidos para um domínio — útil para detectar certificados emitidos por CAs que você não autorizou, o que pode indicar comprometimento ou uso não autorizado. Uma busca periódica por certificados de seus domínios é uma prática de security monitoring válida.
Certificate Pinning
Certificate pinning fixa o certificado ou a chave pública que o cliente aceita, eliminando a confiança na CA chain. Mesmo que uma CA seja comprometida e emita um certificado falso para seu domínio, um cliente com pinning o rejeitará porque não corresponde ao certificado ou à chave pública fixada.
Há dois tipos de pinning:
- Leaf certificate pinning: o cliente fixa o certificado exato do servidor. Mais restritivo — qualquer renovação de certificado (incluindo renovações automáticas do Let's Encrypt a cada 90 dias) quebra os clientes que não foram atualizados.
- Public key pinning (SPKI pinning): o cliente fixa a chave pública. A chave pode ser mantida quando o certificado é renovado — o Let's Encrypt pode emitir um novo certificado com a mesma chave pública. Mais flexível, mas requer disciplina para nunca alterar a chave ao renovar.
HTTP Public Key Pinning (HPKP, RFC 7469) foi um header que implementava key pinning para aplicações web — foi depreciado em 2018 por causar DoS acidental em muitos sites (uma configuração errada tornava o site inacessível por semanas). Para APIs móveis onde você controla tanto o servidor quanto o cliente, pinning ainda é utilizado, mas com backup pins (duas chaves aceitas) e política de atualização de cliente antes de rotacionar chaves.
mTLS — autenticação mútua
TLS padrão autentica apenas o servidor — o cliente verifica o certificado do servidor, mas o servidor não verifica o certificado do cliente. mTLS (mutual TLS) adiciona a verificação em ambas as direções: o servidor também apresenta um certificado ao cliente, e o cliente verifica. Para serviços que precisam de autenticação forte de quem está chamando — comunicação entre microserviços, conexão de dispositivos IoT, APIs para parceiros de alta confiança — mTLS é o mecanismo mais seguro disponível.
# Geração de PKI interna para mTLS entre serviços — com step-ca
# 1. Criar CA raiz
step certificate create root.example.com root.crt root.key \
--profile root-ca --no-password --insecure
# 2. Criar certificado para o serviço A
step certificate create service-a service-a.crt service-a.key \
--ca root.crt --ca-key root.key --profile leaf \
--not-after 8760h # 1 ano
# Nginx — servidor com mTLS obrigatório
server {
listen 443 ssl;
ssl_certificate /etc/certs/server.crt;
ssl_certificate_key /etc/certs/server.key;
ssl_client_certificate /etc/certs/ca.crt; # CA raiz para verificar clientes
ssl_verify_client on; # exigir certificado de cliente
ssl_verify_depth 2; # aceitar cadeia de até 2 níveis
}
Em Kubernetes, service meshes como Istio e Linkerd implementam mTLS transparentemente entre todos os pods do cluster — os sidecar proxies (Envoy no caso do Istio) negociam TLS automaticamente sem mudança no código da aplicação. Cada workload recebe um certificado SPIFFE (Secure Production Identity Framework for Everyone) com identidade criptograficamente verificável, renovado automaticamente. mTLS em service mesh é a prática de zero-trust networking — nenhum tráfego interno é confiável sem autenticação.
Configuração de TLS — o que verificar em produção
O SSL Labs Server Test (ssllabs.com/ssltest) é a ferramenta padrão para avaliar configuração TLS de servidores públicos. O objetivo é rating A ou A+ — o A+ requer HSTS com preloading. Os parâmetros que determinam o rating:
- Protocolo mínimo: TLS 1.2 ou superior. TLS 1.0 e 1.1 desabilitados.
- Cipher suites: apenas suites com forward secrecy (ECDHE, DHE). Remover RC4, 3DES, e suites sem autenticação (anon).
- Troca de chaves: ECDHE com curvas P-256 ou P-384. DHE com parâmetros de pelo menos 2048 bits.
- Certificado: RSA-2048+ ou ECDSA P-256+, cadeia completa enviada, não expirado, SAN correto.
- Cabeçalhos HTTP: HSTS presente com max-age ≥ 180 dias para A+.
Decisões de engenharia
TLS 1.3 exclusivo: padrão para novos serviços internos, APIs sem requisito de suporte a clientes legados. 1 RTT de handshake, zero cipher suites inseguros por construção (GCM e CHACHA20 apenas), forward secrecy obrigatório.
TLS 1.2 + 1.3: quando há clientes externos que você não controla — browsers antigos, SDKs de terceiros, dispositivos IoT com firmware old. Usar Mozilla SSL Config "Intermediate" como baseline. Desabilitar explicitamente TLS 1.0/1.1, RC4, 3DES, e suites sem PFS.
Nunca: TLS 1.0, TLS 1.1, SSL qualquer versão. São quebrados por design (POODLE, BEAST, DROWN) — não "menos modernos".
Let's Encrypt: padrão para a maioria dos casos. Gratuito, DV automático via ACME, renovação automática. Adequado para HTTPS de APIs, portais web, e serviços públicos.
CA comercial (DigiCert, Sectigo): quando o contrato exige OV/EV para compliance, quando há integração com HSM que exige CA parceira, ou quando o cliente/regulador exige certificado de CA específica. Custo elevado, renovação mais lenta.
CA interna (CFSSL, step-ca): para PKI interna — certificados de microserviços, mTLS entre workloads, desenvolvimento local. Nunca exposta na internet pública; trust anchors distribuídos via config management.
Fase 1 (teste): max-age=300 (5 min). Verificar que todos os subdomains têm HTTPS e que nenhuma dependência quebra. Monitorar erros de console no browser.
Fase 2 (estabilização): max-age=2592000; includeSubDomains (30 dias). Se nenhum problema em 1-2 semanas, avançar.
Fase 3 (produção): max-age=31536000; includeSubDomains (1 ano). Manter assim por pelo menos 1 semana antes de considerar preload.
Preload: apenas quando o domínio for permanentemente HTTPS-only. Adicionar preload e submeter a hstspreload.org. Irreversível em curto prazo — remoção leva meses para propagar.
mTLS: autenticação mais forte. A identidade do cliente é criptograficamente verificada em cada conexão; rotação de certificados é automática via service mesh. Overhead de PKI interna e coordenação de certificados. Preferido em arquiteturas zero-trust.
JWT com assinatura (SPIFFE/SVID): alternativa quando mTLS é impraticável. O workload recebe um JWT assinado pela CA da plataforma; o serviço receptor verifica a assinatura. Menor overhead de PKI, funciona entre ambientes distintos.
API key: mais simples, mas segredo compartilhado — rotação é manual, não há autenticidade criptográfica, e um vazamento compromete permanentemente o acesso. Adequado apenas para integrações simples com terceiros onde mTLS é impraticável.
Como praticar
-
Configurar TLS com Let's Encrypt em um servidor real e inspecionar o handshake. Use Caddy (Caddyfile de 3 linhas) ou Certbot em um servidor com domínio real. Verifique o certificado com
openssl s_client -connect seudominio.com:443 -showcerts— observe a cadeia completa de certificados e o protocolo negociado. Use testssl.sh para gerar um relatório completo das cipher suites suportadas. Se não tiver servidor, usemkcertpara criar uma CA local e certificados para desenvolvimento e inspecione o handshake localmente.
Critério: o relatório testssl.sh não mostra vulnerabilidades críticas (POODLE, HEARTBLEED, ROBOT); a cadeia de certificados inclui leaf + intermediário (não apenas o leaf); o protocolo negociado é TLS 1.3 quando o cliente suporta. -
Auditar configuração TLS de serviços externos que você integra. Para cada serviço externo que sua aplicação consome via HTTPS, execute
testssl.sh --fullou o SSL Labs API para verificar a configuração TLS deles. Documente: qual versão TLS mínima aceitam? Quais cipher suites? Há forward secrecy? HSTS ativado? A postura TLS deles é sua superfície de ataque — conexões a serviços mal configurados podem ser interceptadas.
Critério: lista de pelo menos 3 serviços externos auditados com rating explícito (A/B/C) e identificação de risks; se houver serviço com rating C ou pior, proposta de mitigação (proxy interno, notificação ao fornecedor, aceitar risco documentado). -
Implementar mTLS entre dois serviços locais. Crie uma CA raiz com
mkcertoustep certificate create. Emita certificados para um serviço "servidor" e um "cliente". Configure o servidor para exigir certificado de cliente. Faça uma requisição do cliente com o certificado correto (deve funcionar) e sem o certificado (deve retornar 400 Bad Certificate ou similar). Inspecione a diferença no handshake comopenssl s_client -cert client.crt -key client.key.
Critério: requisição sem certificado de cliente retorna erro explícito de TLS handshake (não 401 HTTP — o erro deve ocorrer no nível do protocolo); o log do servidor mostra o CN do certificado do cliente identificando o serviço chamador; a CA raiz está em um arquivo separado do certificado de servidor. -
Implementar progressão de HSTS em um projeto real. Em um serviço com HTTPS funcionando, adicione o header HSTS com
max-age=300e verifique comcurl -I https://seudominio.com. Confirme que todos os subdomains têm HTTPS (liste todos viacrt.shou DNS zone). Atualize progressivamente para 1 hora, 1 dia, 30 dias, 1 ano. Ao final, verifique o status no hstspreload.org checker para saber se o header está correto para preloading.
Critério: o header HSTS está presente em todas as respostas 200 do domínio principal;includeSubDomainssó é adicionado após confirmar que todos os subdomains têm HTTPS; o checker do hstspreload.org reporta "Eligible" no final da progressão. -
Buscar certificados não autorizados via Certificate Transparency. Para um domínio que você controla (ou de sua organização), pesquise no crt.sh por todos os certificados emitidos nos últimos 90 dias:
https://crt.sh/?q=seudominio.com&output=json. Identifique: quantas CAs diferentes emitiram certificados? Há certificados para subdomains que você não conhecia? Há wildcards? Configure um alerta periódico (script cron ou GitHub Action) que notifica quando novos certificados aparecem.
Critério: script de consulta ao crt.sh funciona e produz lista de certificados com data de emissão e CA emissora; pelo menos um certificado identificado além dos esperados (mesmo que legítimo) — confirma que o processo funciona; alerta automatizado configurado e testado.
Perguntas de entrevista
Qual a diferença principal entre TLS 1.2 e TLS 1.3 no handshake? Por que TLS 1.3 é mais rápido e mais seguro simultaneamente?
Velocidade: TLS 1.2 requer 2 round-trips antes que dados da aplicação possam ser enviados (ClientHello → ServerHello/Certificate → ClientKeyExchange → Application Data). TLS 1.3 reduz para 1 RTT: o cliente envia sua parte do key exchange (ECDH public key) no próprio ClientHello, sem esperar a resposta do servidor. O servidor pode derivar as chaves imediatamente e retornar certificado + dados em uma única resposta. O 0-RTT mode do TLS 1.3 permite dados da aplicação no primeiro pacote usando sessões anteriores.
Segurança: TLS 1.3 simplificou removendo funcionalidades perigosas: cipher suites sem forward secrecy (RSA key exchange estático) foram completamente removidas — em TLS 1.3, todo key exchange usa ECDHE com forward secrecy obrigatório. Algoritmos fracos como RC4, 3DES, MD5, SHA-1, RSA sem PFS foram removidos da especificação (não apenas deprecados — não há como negociá-los). O certificado do servidor é enviado criptografado (com a chave derivada do ECDHE), protegendo a identidade do servidor contra sniffers. Menos superfície de ataque, mais garantias por design.
O que é forward secrecy (PFS) e por que um servidor sem PFS é vulnerável a decifração retroativa?
Forward secrecy (Perfect Forward Secrecy) garante que as chaves de sessão de conexões passadas não podem ser decifradas mesmo se a chave privada do servidor for comprometida no futuro. Sem PFS (RSA key exchange estático em TLS 1.2), o processo de key exchange funciona assim: o cliente gera um pre-master secret e o cifra com a chave pública RSA do servidor; o servidor decifra com sua chave privada RSA; ambos derivam as chaves de sessão. Um atacante que captura o tráfego cifrado e posteriormente obtém a chave privada RSA do servidor (por vazamento, vulnerabilidade, ou ordem judicial) pode decifrar todo o tráfego histórico capturado.
Com PFS (ECDHE key exchange), o cliente e servidor geram pares de chaves ECDH efêmeros — específicos para aquela conexão. O pre-master secret é derivado do DH key exchange entre esses pares efêmeros. As chaves efêmeras são descartadas após a sessão. Mesmo com a chave privada RSA do servidor, é impossível recuperar as chaves efêmeras — elas não existem mais. TLS 1.3 tornou PFS obrigatório ao remover RSA key exchange.
O que Certificate Transparency resolve e quais ataques previne? Como um engenheiro usa CT para monitorar seu domínio?
Certificate Transparency resolve o problema de CAs comprometidas ou desonestas emitindo certificados para domínios sem autorização do dono. Antes do CT, um atacante que comprometesse qualquer CA no bundle de trust do browser poderia emitir um certificado válido para qualquer domínio — o que seria validado silenciosamente pelo browser. Isso aconteceu: DigiNotar emitiu certificados falsos para gmail.com em 2011 usados em ataques MITM contra cidadãos iranianos; Comodo emitiu certificados não autorizados para Google, Yahoo, Skype.
Com CT, toda CA deve registrar cada certificado emitido em logs públicos append-only com estrutura Merkle tree. Browsers verificam que o certificado apresentado aparece em pelo menos dois CT logs (via SCTs — Signed Certificate Timestamps). Um certificado emitido sem ser registrado em CT logs é rejeitado pelo Chrome e Firefox. Isso torna impossível emitir certificados silenciosamente — qualquer emissão é pública e detectável.
Para monitorar seu domínio: a API pública do crt.sh (https://crt.sh/?q=seudominio.com&output=json) retorna todos os certificados conhecidos. Um script cron que monitora novos certificados e notifica via Slack/email é uma prática de security monitoring válida — permite detectar phishing (alguém emitindo certificado para subdomínio parecido), shadow IT (times emitindo certificados sem aprovação), e comprometimento de CA.
Por que HSTS preload é difícil de reverter? Qual é o risco de ativá-lo prematuramente e como mitigar?
A lista HSTS preload é distribuída dentro dos binários dos browsers (Chrome, Firefox, Safari, Edge). Quando um domínio está na lista, o browser nunca faz requisições HTTP para ele — mesmo na primeira visita, mesmo que o usuário nunca tenha acessado o site antes. Isso é a vantagem: elimina completamente a janela de vulnerabilidade do primeiro acesso HTTP.
O problema de reversibilidade: remover um domínio da lista requer submeter um pedido de remoção ao hstspreload.org, que é aceito, e depois aguardar que a lista atualizada seja incluída no próximo release de cada browser (Chrome, Firefox, Safari, Edge têm releases com ciclos distintos — meses). Durante esse período, usuários com versões de browser que contêm a entrada antiga não conseguem acessar o domínio via HTTP. Se qualquer recurso do domínio (subdomains incluídos com includeSubDomains) não tiver HTTPS válido, o acesso fica bloqueado sem saída de emergência — sem modo incógnito, sem configuração, nada.
A mitigação é a progressão gradual: verificar que 100% dos subdomains têm HTTPS válido (usar crt.sh para listar todos), testar HSTS com max-age pequeno por semanas, aumentar gradualmente, e só submeter para preload quando o domínio for permanentemente HTTPS-only sem plano de retorno.
Qual a diferença entre mTLS e API key para autenticação entre microserviços? Quando mTLS é justificável?
API key: um segredo compartilhado enviado no header HTTP. Simples de implementar, mas: (1) o segredo precisa ser distribuído e armazenado em cada cliente — um vazamento compromete permanentemente o acesso; (2) não há autenticidade criptográfica — qualquer um com a chave pode usá-la; (3) rotação é manual e requer coordenação de deployment; (4) sem forward secrecy — se o canal TLS for comprometido, as chaves ficam expostas no header.
mTLS: autenticação via certificado cliente apresentado durante o handshake TLS. Não há segredo transmitido na camada HTTP — a autenticação ocorre no nível do protocolo. A identidade do chamador é criptograficamente verificada (o servidor sabe que o cliente tem a chave privada do certificado). Rotação automática em service meshes com SPIFFE. O compromisso de um serviço não implica comprometimento dos outros.
mTLS é justificável quando: (1) o ambiente é zero-trust e tráfego interno não é confiável por design; (2) há um service mesh (Istio, Linkerd) que implementa mTLS transparentemente sem mudança de código; (3) o compliance exige autenticação criptográfica de workloads; (4) há requisito de auditabilidade — "qual serviço exatamente fez esta chamada?" com garantia criptográfica. Não é justificável quando a infra de PKI interna seria mais cara de operar que o risco mitigado — monolitos ou sistemas com poucos serviços frequentemente têm VPC isolation suficiente.
Referências para aprofundar
- docs RFC 8446 — The Transport Layer Security (TLS) Protocol Version 1.3 — IETF.
- book Bulletproof TLS and PKI — Ivan Ristić (Feisty Duck, 2nd ed. 2022).
- article TLS 1.3 is Here to Stay — Ristić (blog.qualys.com, 2018).
- docs Let's Encrypt — How It Works.
- docs RFC 6797 — HTTP Strict Transport Security (HSTS) — IETF.
- docs HSTS Preload — hstspreload.org.
- article POODLE Attack — SSL 3.0 Vulnerability — Möller, Duong, Kotowicz (Google, 2014).
- docs SPIFFE — Secure Production Identity Framework (spiffe.io).
- article An Illustrated Guide to TLS 1.3 — Michael Driscoll.
- vídeo TLS — Illustrated — Hussein Nasser (YouTube).
- docs Mozilla SSL Configuration Generator.
- article Certificate Transparency — How It Works — Google.