Repository navigation
mTLS Traefik ↔ backend: o apiServer exige certificado de cliente da CA do RPC (#90) - #113
Merged
Merged
Conversation
…endency_overrides (#90)
… contexto confia só na CA do RPC (#90)
…I_TLS_* existe (#90)
…heck, assinadas pela CA do RPC (#90)
…o TLS sai com 78 e nomeia a variável (#90) Achados do checkpoint de revisão: HttpServer.listenOn cria o servidor com _closeServer=false, então o shutdown deixava a 8080 ocupada e aceitando handshakes; e o StateError/TlsException do boot escapava do run() async void para o runZonedGuarded da #56, que loga só o tipo (e classifica a TlsException como transitória, saindo com código 0).
…ck autenticado; backend exige a CA do RPC (#90)
… outra CA recusados, com certificado 200 (#90)
…Serverpod e issue upstream registrados (#90)
…GRESS corrige os suspeitos da regressão do acs_full_e2e (#90)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fecha a #90 (continuação da #78 / PR #89): o trecho Traefik → backend passa a TLS 1.3 mútuo. O backend exige, no handshake da 8080 interna, um certificado de cliente assinado pela CA de desenvolvimento do RPC; o Traefik apresenta o seu pelo
serversTransport.certificates; qualquer processo na rede do Compose sem o certificado é recusado antes de qualquer byte HTTP.Plano executado:
docs/superpowers/plans/2026-10-27-issue-90-mtls-traefik-backend.md(decisões do dono registradas em 2026-10-27).Antes / depois (comando-evidência, outro container na rede
sinalacs_default){"__className__":"ServiceHealth","status":"ok",…}/HTTP 200(o servidor nunca enviavaRequest CERT)curl: (56) … SSL_ERROR_SYSCALL/HTTP 000— nenhuma linha HTTPDecisão de arquitetura (ADR em
spec/stack.md)O Serverpod é consumido por um fork pinado por SHA (
hbgit/serverpod@2a0b67e,dependency_overridesembackend/pubspec.yaml, patch versionado embackend/patches/). Motivo medido:Server.startchamaRelicApp.servefixo no 3.4.13, 4.0.4 e 4.1.0-rc.1; orelic_ionão expõerequestClientCertificate; e oHttpServer.bindSecuredo SDK só pede o certificado — comrequestClientCertificate: trueo handshake completa sem certificado (seria 401 na aplicação, não recusa). A recusa exigeSecureServerSocket.bind(requireClientCertificate: true)+HttpServer.listenOn, só possível se a aplicação ligar o socket. O patch é um gancho genérico (apiServerAdapterFactory), proposto upstream contra omain: serverpod/serverpod#5923. Critério de saída e custo de upgrade embackend/patches/README.md.O que muda
ApiTlsConfig:API_TLS_CLIENT_CA_PATHobrigatória junto com cert e chave; subconjunto (um.envanterior à mTLS Traefik ↔ backend bloqueado pelo Serverpod (requestClientCertificate) #90) → mensagem com as três no stderr e exit 78, nunca TLS de mão única em silêncio.lib/src/runtime/mtls_api_server.dart: bind comrequireClientCertificate: true, embrulhoServerSocketcomhandleError(recusas contadas, log só do tipo), adapter cujoclosefecha o socket (olistenOndo SDK não fecha).traefik-init: duas folhasclientAuthdistintas —traefik-client(chave 600, só o Traefik) ehealthcheck(CN próprio, 90 dias, 644).dynamic/tls.yaml:certificatesnobackend-tls(serverName/rootCAsintocados). Compose:API_TLS_CLIENT_CA_PATH, healthcheck com a folha dele.pubspec.yamlreal para o override sobreviver ao build (clone anônimo do fork público).Provas
dart test -j 11573/1573; novosapi_tls_config_test(11),mtls_api_server_test(9),server_wiring_test,serverpod_fork_test.scripts/qa/tls_invariants.sh20/20; Grupo E reescrito para sondar de fora da rede: E5 sem certificado e E6 outra CA (mesmo CN) recusados; E2 com certificado 200; E3 TLS 1.2 recusado; E8 20 recusas seguidas sem derrubar o listener (RestartCount=0); E4 cobracertificates+API_TLS_CLIENT_CA_PATH; E7 EKU clientAuth +openssl verify; E9 folha do healthcheck > 7 dias e distinta.certificates→ 502 e E4 acusa; (b) semAPI_TLS_CLIENT_CA_PATH→ exit 78 com a mensagem exata, Grupo A acusa; (c)requireClientCertificate: false→ E5/E6 acusam; (d) wrapper relançando comoStateError→ segue verde (o SDK/relic protegem; ohandleErroré defesa em profundidade).mtls_invariants.sh4/4,dev_key_permissions_test.shok,cobertura_prd.py --finalok.emulator-5554, API 36):e2e.sh --emulator --keepverde (live_check do paciente e do ACS + smoke dos dois apps pelo Traefik).acs_full_e2e.sh: 5/6 em duas execuções — falha só o 1º teste, numtaplocal emsync_visitscoberto pela SnackBar "visita salva", antes de qualquer rede;apps/é idêntico aodevelop; o último verde desse script é o da [P1] Telemetria estruturada dos eventos do §1.3 (North Star e hipóteses) #83 (2026-10-25) e depois deleapps/acsmudou em ACK de alerta já concluído devolve "acknowledged" e o botão de concluir reaparece (RF05) #86 (e70e0c3, perto doshowSnackBar) e ACK repetido reescreve o ACS do alerta e audita "acknowledged" de novo #88 (6b8c8dc) — regressão pré-existente do e2e, fora desta issue (verPROGRESS.md; issue própria a abrir).Critérios da issue
serversTransport.certificates)HTTP 000), mutação (c)Fora do escopo e intocados: Postgres, Gorush, 8082/8083, 8081 — RNF04 segue parcial por eles. Abertos: produção (no Render o TLS termina na borda), rebase do fork a cada upgrade, o backend não loga o CN do cliente, rede interna como defesa em profundidade.
🤖 Generated with Claude Code