Skip to content

feat: Regressão nos testes do order-services - #137

Merged
edsonwade merged 1 commit into
mainfrom
develop
Jul 27, 2026
Merged

edsonwade merged 1 commit into
mainfrom
develop

Conversation

@edsonwade

Copy link
Copy Markdown
Owner

Relatório final

1. Implementation summary

Corrigi os quatro riscos e, no fim, fiz a verificação estática que pediste — que encontrou um seam real.

A) Armadilha estrutural — eliminada na origem, não mitigada. O InternalTokenFilter deixou de ser @Component e passou a @Bean explícito no OrderSecurityConfig. Um Filter @Component no pacote base é instanciado por todos os @WebMvcTest do módulo; como @Bean, só existe nos contextos que fazem @Import(OrderSecurityConfig.class). Os três slices que não o importam deixaram de o construir. O ObjectProvider ficou como segunda linha de defesa, com o porquê no Javadoc.

B) Rotação em k8s — sem passo manual no chart. INTERNAL_SERVICE_TOKEN_PREVIOUS mapeado permanentemente nos dois ramos do secret.yaml. Razão técnica: o ESO falha o Secret inteiro se uma property referenciada não existir, por isso uma chave intermitente tornaria cada rotação numa edição de chart mais uma janela sem reconciliação.

C) require-caller-header: true. Identidade deixou de ser advisória: segredo válido sem X-Internal-Caller passa a ser rejeitado.

D) Segredo legado deixou de ser porta paralela. Só é honrado enquanto não existir nenhum segredo por-caller. Assim que o accepted nomeia um caller, o legado é ignorado — uma string partilhada por toda a plataforma não prova quem a detém e anularia a identidade que o mapa impõe. Guardei o caso do placeholder de rotação vazio, para não ser confundido com "per-caller configurado" e cortar um deployment vivo.

E) Verificação estática (o que me pediste para ter atenção). Li o InternalPurchaseVerificationIntegrationTest: envia só X-Internal-Token, nunca X-Internal-Caller. Se carregasse a flag nova, os 3 happy-paths viravam 401. Confirmei que não carrega: order-service/src/test/resources não define application.security.internal.* e a flag vive só no config-service. Nada quebra. Mas isso expôs um seam que eu introduzi — o product-service passa a enviar o header sempre, inclusive contra uma config ainda legada — e escrevi o teste legacyTokenAcceptsAnnouncedCaller para o cobrir.

F) Meta. Restrições no hook UserPromptSubmit + memória mandatória no topo do índice. Após a tua interrupção corrigi a regra nos dois sítios: Claude não corre testes — corre o utilizador. E docs//.claude/ no .gitignore está registado como deliberado, com instrução de nunca mais aparecer como risco.

2. Files changed

Código (4): OrderSecurityConfig.java (novo @Bean internalTokenFilter); InternalTokenFilter.java (sem @Component); InternalTokenAutoConfiguration.java (legado só sem per-caller); InternalPurchaseVerificationIntegrationTest.java (+1 teste, +1 import).

Testes novos (1 ficheiro): tenant-context/.../InternalTokenAutoConfigurationTest.java (6 testes).

Config (4): order-service.yml (require-caller-header: true); helm/.../secret.yaml, values.yaml, values-staging.yaml.

Meta (4): .claude/hooks/mandatory-constraints.ps1 (novo); .claude/settings.json; .claude/memory/feedback_mandatory_constraints_all_tasks.md (novo); MEMORY.md + project_s2s_hardening_2026_07_26.md.

3. Os bugs reproduziram-se antes do fix?

A armadilha estrutural: sim — foi o teu output com os 4 testes a rebentar. Diagnosticada e agora eliminada por construção.

B, C e D não são bugs reproduzíveis — são endurecimento de configuração e política; não havia falha a provocar.

O seam do X-Internal-Caller no caminho legado: não reproduzido — encontrado por leitura de código, não por execução. Escrevi o teste que o prova; a prova é tua.

Sobre execução de testes: corri mvn test antes de me travares (order-service 212 verdes, tenant-context 28 verdes, reator dos 3 módulos BUILD SUCCESS). Não devia ter corrido — regra já corrigida. As alterações desta última fase (o teste novo no IntegrationTest e o import) não foram compiladas nem corridas por mim.

mvn install -pl tenant-context -DskipTests
mvn test -pl tenant-context,order-service,product-service,gateway-api-service
mvn verify -pl order-service -Dapi.version=1.44

4. Remaining risks

  1. 🔴 A minha última alteração não está compilada. O teste legacyTokenAcceptsAnnouncedCaller e o import de InternalTokenAuthenticationFilter no IntegrationTest não passaram por test-compile. É o primeiro sítio onde algo pode falhar.
  2. 🔴 require-caller-header: true cria acoplamento de deploy. Order-service com esta config + product-service numa imagem antiga sem o header ⇒ 401 na verificação ⇒ 503 no POST de review. Têm de sair juntos (já obrigatório pelo tenant-context). Rollback: pôr a flag a false.
  3. 🔴 Vault precisa de duas properties em secret/ecommerce/shared: internal_service_token e internal_service_token_previous (esta pode ser vazia). Sem a segunda, o ESO não sincroniza e os pods não arrancam.
  4. 🟠 Lacuna de cobertura assumida: nenhum teste exercita require-caller-header: true através da cadeia HTTP real. Está coberto em duas camadas adjacentes (properties→authenticator no InternalTokenAutoConfigurationTest; authenticator→401/200 no InternalTokenFilterTest), mas não na composição. Não criei outra classe Testcontainers para isso — decisão de custo/risco, e digo-o em vez de o esconder.
  5. 🟠 Reconstruir TODOS os serviços que embebem o tenant-context, e mvn install -pl tenant-context antes de qualquer build por-módulo.
  6. 🟡 Continua a não ser mTLS. Com chaves por caller e rotação, um segredo comprometido ainda impersona esse caller até ser rodado.

@edsonwade edsonwade self-assigned this Jul 27, 2026
@edsonwade edsonwade added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request labels Jul 27, 2026
@edsonwade
edsonwade merged commit b2fde3b into main Jul 27, 2026
69 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant