0018 — Adota xadm-seguranca: infra transversal de auth vem da lib¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-09 · Decidido em: 2026-08-11
Contexto. O Integrador foi a fonte da extração da xadm-seguranca — o
SessionAuthenticationFetcher local (sessão JWT das views, login Firebase) é o código de
onde a lib nasceu. Enquanto a lib não existia, o app carregava essa infra transversal em
br.com.xadm.comum; 0016/0017
declararam explicitamente que adotar a xadm-seguranca estava fora de escopo (o fetcher local
bastava para o gate da tela). Com a lib publicada e endurecida, essa infra vira recópia de código
da casa — constituição §5 Baseline (app Micronaut consome as libs transversais, não as espelha). É a
Fase 2 da iniciativa libs+contrato (a Fase 1 foi a xadm-comum-web, 0017). Este DR revoga a
nota "fora de escopo" de 0016/0017.
Decisão.
- Adotar
xadm-seguranca:0.3.0; dropar a infra transversal local. Seis classes de auth —AuthException,AuthSettings,MicronautProfiles,FirebaseIdTokenValidator,SessionTokenService,SessionAuthenticationFetcher— eram equivalentes às da lib (só pacote/javadoc diferiam) e saíram debr.com.xadm.comum; imports repointados parabr.com.xadm.comum.seguranca.*. Os testes que exercitavam API package-private da lib (SessionTokenServiceTest,FirebaseIdTokenValidatorTest,MicronautProfilesTest) foram removidos — a cobertura dessa mecânica agora é responsabilidade do repoxadm-commons. - Política de auth fica local (por desenho). A lib traz a infra; a policy é per-app e
permanece em
br.com.xadm.comum:ViewSecurityRule(tri-estado enabled/bypass/fail-closed),ViewRejectionHandler(302/401/403/503),ApiBearerSecurityRule, e oAuthSupport(whitelist de paths + atributos de request). Mesmo nome de conceito ≠ mesma decisão — a whitelist e o tri-estado são escolhas deste app. StaticBearerTokenValidatorfica local via@Replaces. A lib 0.3.0 já endureceu a comparação (constant-timeMessageDigest.isEqual+ guard de vazio — o feedback §6 do ciclo anterior landou na lib), mas lê${app.api-token}. Este app lê${api.bearer.token}(envINTEGRADOR_API_TOKEN, já injetada por tenant no Coolify) — adotar a da lib exigiria renomear o secret de deploy. O@Replaces(br.com.xadm.comum.seguranca.StaticBearerTokenValidator.class)neutraliza o bean da lib sem duplicar validação divergente. Paridade de segurança preservada.- SUPERADO em 2026-08-21 (
d2c7d60): o bean local foi removido e o app adotou oStaticBearerTokenValidatorda lib, renomeando a property deapi.bearer.tokenparaapp.api-token— a env de deploy continuaINTEGRADOR_API_TOKEN, que era o custo que esta decisão queria evitar; ele não existia, porque o que precisava mudar era o nome da property, não o do secret. O@Replacesdeixou de existir junto. Manter cópia local de validador só para conservar um nome de property contrariava o próprio Baseline que este DR adotou. Com isso o app passou a herdar as guardas de boot da lib: placeholder${...}não resolvido (0.5.1) e, desde a 0.7.2,app.api-tokendeclarado e vazio (BearerTokenGuard) — fora dedev/test, os dois recusam o boot. Estado atual em dev/seguranca.md. auth.issuervirou config. A lib generalizou oISSUERantes hardcoded ("integrador") para${AUTH_ISSUER:integrador}e exige não-vazio no boot (oSessionTokenServiceda lib falha o contexto senão). O default preserva o valor histórico — deploy existente não muda de comportamento.
Consequências. ./gradlew check sobe o contexto com a xadm-seguranca no classpath e a suíte de
auth existente (SecurityRulesTest, AuthSupportTest, LoginControllerTest, GoogleLoginFlowIT,
ViewSessionAuthIntegrationTest, LoginPageRenderingIT, NavbarRenderingIT) segue verde — prova de
paridade. O feedback de timing-attack do StaticBearer está resolvido na lib 0.3.0. Correção de
segurança na casa passa a chegar ao app por bump de versão, não por edição local.
Fora de escopo: a xadm-seguranca em si (repo xadm-commons); adotar CSRF da lib (o
SessionAuthenticationFetcher da lib popula o atributo auth.csrf, mas a verificação segue onde
está — sem mudança de comportamento de CSRF neste ciclo).
Revisto: o 0019 (seguranca 0.4.0) adotou o CSRF de sessão via
CsrfTokens e deduplicou o AuthSupport local (constantes/isHttps vêm da lib; a whitelist
virou ViewWhitelist).