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):
- Modo A: JWT ECOSIF (HS512) via
jwt_validator+auth_middleware - Híbrido / Modos B e C:
HYBRID_ECOSIF_AZURE,AZURE_ENTERPRISE_GATEWAY(JWKS Entra) eGOOGLE_GATEWAY(JWKS Google +identity_provider_link) - Autorização:
access_control/user_repository(empresa/filial; ADMIN bypass) /healthpúblico; Swagger só seECOSIF_COMPLIANCE_SWAGGER_ENABLED=true
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 + exp — OK |
| 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
- Sem token / inválido / expirado → 401 JSON
{"message":"Invalid Token"}(paridade masterdata) - Usar
AuthenticationFailurejá existente noerror_handler.py
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
- Atualizar
ecosif-structure/docs/gateway-jwt-ecosif.md— incluir/ecosif-compliance/*nas rotas protegidas - Pen test: estender checklist AUTH com seção compliance
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 sub → gr_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/sub → identity_provider_link → gr_user |
user_repository.find_user_by_google_claims |
sub → identity_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
- [x] Nenhum endpoint
/api/compliance/*responde 200 sem token válido (exceto health) — middleware Modo A - [x] JWT emitido por
signin/external-loginaceito (mesmoAUTH_TOKEN_SECRET/ claims) - [x]
AUTH_TOKEN_SECRETeECOSIF_JWT_SUBJECT_CLAIMalinhados aos Java na stack (ecosif-structure) - [x] Compose:
ECOSIF_COMPLIANCE_AUTH_ENABLED+ secret compartilhado - [x] (Fase 2) Acesso por empresa/filial via
access_control/gr_filial_usuario - [ ] Documentação gateway structure com rotas
/ecosif-compliance/*revalidada - [ ] Pen test / smoke automatizado específico compliance
- [x] (Fase 3)
HYBRID_ECOSIF_AZURE+AZURE_ENTERPRISE_GATEWAY(JWKS Entra + link) - [x] (Fase 3)
GOOGLE_GATEWAY(JWKS Google + link)