Autenticação — alinhamento com microsserviços Java (Modos A/B/C)

Prioridade: crítica (ambiente bancário / contabilidade regulada)
Status: Fase 1 (Modo A) e Fase 2 (acesso empresa/filial) implementadas · Fase 3: HYBRID_ECOSIF_AZURE, AZURE_ENTERPRISE_GATEWAY e GOOGLE_GATEWAY implementados
Módulo: ecosif-compliance (Flask/Python)
Relacionado: AUTH-01 Modo A, AUTH-09 MVP5 / P7-E / P7-06, gateway-jwt-ecosif.md, gateway_hibrido_ecosif_azure.md, gateway_access_token_google.md


Situação

Antes do middleware, a API REST não validava Authorization: Bearer — qualquer cliente com acesso de rede podia listar regras, disparar /api/compliance/run e baixar resultados.

Hoje (com ECOSIF_COMPLIANCE_AUTH_ENABLED=true, default na stack):

O Angular continua enviando JWT pelo interceptor.


Objetivo

Mesmo contrato dos serviços Java:

Modo ECOSIF_API_TOKEN_MODE Token em Authorization Validação no compliance
A ECOSIF_JWT JWT ECOSIF (HS512) AUTH_TOKEN_SECRET + expOK
Híbrido HYBRID_ECOSIF_AZURE HS → ECOSIF; RS/ES/PS → Azure Paridade Java P7-E — OK
B AZURE_ENTERPRISE_GATEWAY Access Token Microsoft JWKS Entra + aud + link — OK
C GOOGLE_GATEWAY Token Google JWKS Google + aud + link — OK

Defense in depth: gateway e aplicação validam o mesmo tipo de token.


Arquitetura proposta

Angular (logado)
  → Authorization: Bearer <token conforme apiTokenMode>
  → nginx / Traefik / APIM
  → ecosif-compliance (middleware Python)
       ├─ Modo A: PyJWT HS512 + AUTH_TOKEN_SECRET
       ├─ Modo B: PyJWT/JWKS Microsoft
       └─ Modo C: PyJWT/JWKS Google
  → rotas /api/compliance/* (autenticadas)
  → /health (público — healthcheck)
  → /docs (público só em dev; desligado em prod)

Fase 1 — Modo A (obrigatória antes de produção)

Escopo: ~3–5 dias · pode ir em paralelo ao fechamento F5 do AUTH-01.

1.1 Biblioteca e middleware

Novo pacote app/security/:

Arquivo Função
jwt_validator.py Valida JWT ECOSIF (sub, iat, exp, assinatura HS512)
auth_middleware.py before_request no Flask — extrai Bearer, popula g.ecosif_user
auth_config.py Lê env: AUTH_TOKEN_SECRET, ECOSIF_JWT_SUBJECT_CLAIM, ECOSIF_API_TOKEN_MODE

Dependência: PyJWT[crypto]>=2.8.

1.2 Rotas públicas (igual Java)

Rota Motivo
GET /health Docker / ALB healthcheck
OPTIONS * CORS preflight

Produção: ECOSIF_COMPLIANCE_SWAGGER_ENABLED=false — ocultar /docs.

1.3 Variáveis (docker-compose + ECS)

Repassar as mesmas do auth/masterdata:

AUTH_TOKEN_SECRET=...          # obrigatório — idêntico aos Java
TOKEN_EXPIRATION=1800000       # documentação; validação via claim exp
ECOSIF_JWT_SUBJECT_CLAIM=username
ECOSIF_API_TOKEN_MODE=ECOSIF_JWT

1.4 Respostas de erro

1.5 Testes

Teste Esperado
GET /api/compliance/rule/list sem Bearer 401
Com JWT de signin 200
JWT adulterado 401
GET /health sem Bearer 200

1.6 Gateway + docs

1.7 Angular

Nenhuma mudança obrigatória — interceptor já envia JWT. Validar telas (balancete, etc.) após deploy.


Fase 2 — Autorização por tenant/empresa (recomendada p/ bancos)

Autenticação (quem é) ≠ autorização (o que pode).

Hoje o compliance aceita companyid / company no body sem checar se o JWT pertence a quem pode ver aquela empresa.

Entrega Descrição
Resolver subgr_user + tenant Query leve no PostgreSQL (mesmo DB)
Validar companyid contra useraccess / tenant Antes de run e downloads
Role ADMIN vs STAFF Opcional: regras de escrita em /rule/add

Estimativa: +3–5 dias após Fase 1.


Fase 3 — Híbrido, Modo B e Modo C (AUTH-09)

Implementado em app/security/ (espelho do starter Java):

Componente Função
jwt_validator.validate_api_token Roteia por ECOSIF_API_TOKEN_MODE e, no híbrido, pelo alg (HS → ECOSIF; RS/ES/PS → Azure)
azure_jwt_validator.py JWKS Entra (PyJWKClient), iss + aud + exp
google_jwt_validator.py JWKS Google, iss + aud (CLIENT_ID) + exp
user_repository.find_user_by_azure_claims oid/subidentity_provider_linkgr_user
user_repository.find_user_by_google_claims subidentity_provider_link (GOOGLE) → gr_user

Variáveis Azure / híbrido:

ECOSIF_API_TOKEN_MODE=HYBRID_ECOSIF_AZURE   # ou AZURE_ENTERPRISE_GATEWAY
ECOSIF_AUTH_PROVIDER=AZURE_ENTERPRISE
ECOSIF_AZURE_TENANT_ID=...
ECOSIF_AZURE_API_AUDIENCE=api://...
AUTH_TOKEN_SECRET=...                      # obrigatório no híbrido (ramo HS*)

Variáveis Google (Modo C):

ECOSIF_API_TOKEN_MODE=GOOGLE_GATEWAY
ECOSIF_AUTH_PROVIDER=GOOGLE
ECOSIF_GOOGLE_CLIENT_ID=<oauth-web-client>.apps.googleusercontent.com
ECOSIF_GOOGLE_EXPECTED_ISSUER=https://accounts.google.com
# ECOSIF_GOOGLE_EXPECTED_AUDIENCE=   # vazio = CLIENT_ID

Alternativas descartadas

Alternativa Motivo
Só gateway, sem validação no Flask Insuficiente para ambiente crítico (bypass direto na porta 8021)
Reescrever compliance em Java Custo alto; DSL/PLY em Python
API key só no compliance Não alinha com Modos A/B/C do produto

Ordem de execução recomendada

1. Fase 1 Modo A no compliance     ← bloqueante produção
2. Gateway + pen test compliance
3. Fase 2 autorização tenant       ← recomendado bancos
4. Fase 3 Modo B/C com MVP5        ← junto AUTH-09 P7-01

Critérios de aceite


Referências