Objetivo: substituir o certificate pinning (quebrado pela rotação do auto cert da Imperva) por autenticação mútua (mTLS) — o app prova identidade com um client certificate assinado pela sua CA e validado pela Imperva na borda. O backend de negócio não muda.
Princípios:
┌──────────────────────┐
│ Mobile App │
│ (chave no Keystore/ │
│ Keychain; CSR; │
│ cert no cofre) │
└──────────┬───────────┘
│ ① CSR / ② cert (HTTPS autenticado)
▼
┌──────────────────────┐ ③ IssueCertificate(CSR) ┌──────────────────────┐
│ Enrollment Service │ ──────────────────────────────► │ AWS Private CA │
│ (API Gateway + │ │ • raiz OFFLINE │
│ Lambda) │ │ • subordinada │
└──────────┬───────────┘ │ (clientAuth EKU) │
│ │ • chave da CA em KMS│
│ ④ upload da CA subordinada + settings └──────────────────────┘
▼
┌──────────────────────┐ mTLS handshake (client cert) ┌─────────────┐
│ Imperva │ ◄────────────────────────────────── │ Mobile App │
│ valida o client cert│ (servidor: auto cert rotacionado) └─────────────┘
│ contra sua CA │
└──────────┬───────────┘
│ TLS (HTTP)
▼
┌──────────────────────┐
│ Backend (intocado) │ ← identidade do cliente chega via
└──────────────────────┘ header `clientCertificateInfo`
Até aqui o mTLS resolve a direção cliente → servidor: a Imperva valida o client cert e sabe que a chamada veio de um device com cert emitido pela sua CA. A pergunta inversa é: como o app sabe que está falando com o servidor legítimo (e não com um MITM)?
1. Validação padrão do TLS (base)
HttpClient/Dio) — não exige pinning.2. Por que o MITM não passa
3. Como saber que a chamada vem do app legítimo (cert não roubado)
fingerprints allowlist na Imperva como controle duro.4. Reforços no app (Flutter)
badCertificateCallback apenas em builds de debug, nunca em prod).CA:TRUE, pathLenConstraint:1) → emitir subordinada → desativar a raiz (fica offline).clientAuth → esta é a âncora que você sobe na Imperva.clientAuth (ou ApiPassthrough para EKU vir do CSR).| Camada | Detalhe |
|---|---|
| Endpoint | POST /enroll — recebe CSR (PEM) + token |
| Auth | Autorizador valida token do seu IdP (Cognito/OIDC) ou device attestation |
| Lambda | chama acm-pca:IssueCertificate → polling GetCertificate → devolve {cert, chain} |
| IAM | role com acm-pca:IssueCertificate, acm-pca:GetCertificate |
| Validade | 30–90 dias (curta, rotação natural) |
| Extras | rate-limit, audit (CloudTrail), endpoint admin POST /revoke (RevokeCertificate) |
# 1) Sobe a CA subordinada (a que assina os client certs)
resource "incapsula_mtls_client_to_imperva_ca_certificate" "client_ca" {
certificate_name = "mtls-client-ca"
certificate = filebase64("./ca_subordinada.pem")
account_id = data.incapsula_account_data.account_data.current_account
}
# 2) Associa a CA ao site
resource "incapsula_mtls_client_to_imperva_ca_certificate_site_association" "assoc" {
certificate_id = incapsula_mtls_client_to_imperva_ca_certificate.client_ca.id
site_id = incapsula_site.example-site.id
}
# 3) Exige o client cert e repassa identidade ao origin
resource "incapsula_mtls_client_to_imperva_ca_certificate_site_settings" "cfg" {
site_id = incapsula_site.example-site.id
require_client_certificate = true
is_disable_session_resumption = true # se mTLS só em hosts/portas específicos
forward_to_origin = true
header_name = "clientCertificateInfo"
header_value = "COMMON_NAME" # ou FULL_CERT/FINGERPRINT/SERIAL_NUMBER
depends_on = [incapsula_mtls_client_to_imperva_ca_certificate_site_association.assoc]
}
Rotação da CA: o recurso não suporta update → criar nova CA, associar, migrar, deletar a antiga. Lockdown extra:
fingerprints(SHA1) — allowlist dos certs de cliente, além da CA.
Contexto técnico
SecurityContext do dart:io → o mTLS exige uma camada nativa (plugin ou ponte própria via platform channel).Fluxo de enrollment (Flutter)
Dependências sugeridas (validar no pub.dev na data da implementação)
flutter_secure_storage — guarda o cert (PEM) e metadados de forma cifrada; a chave privada permanece no cofre do SO via código nativo.Pinning de servidor no app
Ciclo de vida no app
RevokeCertificate + validade curta; fingerprints allowlist como controle duro complementar (revogação ao vivo na Imperva depende de CRL/OCSP).| Fase | Entrega |
|---|---|
| 1. PKI | Private CA (raiz offline + subordinada) |
| 2. Sanidade | Validar na Imperva com openssl s_client + cert de teste |
| 3. Enrollment | API Gateway + Lambda (/enroll, /revoke) |
| 4. Imperva | Terraform (upload CA, associação, require_client_certificate) em site de staging/rota de teste |
| 5. App | Integração no app (Flutter) — enrollment + mTLS |
| 6. Rollout | Staging → canary → prod; manter soft pin (report) durante a transição; monitorar falhas de handshake |