Arquitectura tecnológica — Vista Azure (Enterprise AI Platform)¶
Propósito: vista técnica detallada pero legible de cómo está armado el sistema en Azure, qué integra (APIM, Entra, Foundry, SonarQube, ADO, Monitor) y qué hace cada pieza.
Ámbito: as-built Finance DEV (Mexico Central + AI en East US 2 donde aplica).
Complemento de onboarding: getting-started.md · Demo: demo-script.md
Orden de lectura
Si llegás desde el inicio: primero esta vista → luego guion de demo. Detalle de identidad en entra-apim-finance.md.
1. Mapa mental (qué hay encima de qué)¶
[Usuario] → Entra ID (login)
→ finance-web (ACA)
→ proxy /api/finance/*
→ APIM (JWT · grupos · rate limit)
→ finance-api (ACA)
→ SQL | Blob | Document Intelligence | Foundry
Regla de oro: el navegador no llama al FQDN público del API; el portal Next hace de BFF (Backend-for-Frontend) y manda el Bearer a APIM.
2. Diagrama de arquitectura (Azure as-built)¶
flowchart LR
U[Usuario] --> ENTRA[Entra ID]
U --> WEB[finance-web]
ENTRA -.-> WEB
WEB -->|JWT| APIM[APIM]
APIM --> API[finance-api]
API --> SQL[(SQL)]
API --> BLOB[(Blob)]
API --> DI[Doc Intelligence]
API --> FO[Foundry]
FO -->|tools| API
API --> OBS[App Insights / Monitor]
ADO[Azure DevOps] -->|deploy| WEB
ADO -->|deploy| API
Nombres de recurso y detalle de capas: sección 3. Inventario.
3. Inventario de recursos (nombres reales DEV)¶
| Capa | Recurso | Nombre / nota |
|---|---|---|
| Contenedor | Resource Group | rg-eai-dev-mxc |
| Borde (manual) | Front Door + WAF | rg-honne-edge-shared · edge-front-door.md |
| Compute | Container Apps Environment | cae-eai-dev (Consumption, sin VNet) |
| Compute | Container App | ca-eai-finance-web-dev |
| Compute | Container App | ca-eai-finance-api-dev |
| Compute | Container App | ca-eai-mcp-sup-dev |
| Gateway | API Management | apim-eai-dev-fz1d (SKU Developer) |
| Datos | SQL Server / DB | sql-eai-dev-fz1d / sqldb-eai-finance-dev |
| Datos | Storage | Account del RG · container invoices |
| Secretos | Key Vault | kv… en RG (RBAC) |
| Identidad workload | User Assigned MI | Apps usan MI hacia Azure |
| AI | Document Intelligence | Región ai_location (eastus2) |
| AI | Foundry | ais-eai-foundry-dev · agent eai-finance-agent |
| Obs | Log Analytics | log-eai-dev-mexicocentral |
| Obs | App Insights | appi-eai-… |
| Obs | Action Group | ag-eai-dev-ops |
| Registry | ACR | acreaidevfz1d |
| CI | Azure DevOps | proyecto Enterprise-AI-Platform |
| Calidad | SonarQube | proyectos enterprise-ai-finance-api / -web |
IaC: Terraform en infra/environments/dev/ · state remoto en rg-eai-tfstate-mxc.
4. Capas tecnológicas (detalle mínimo útil)¶
4.1 Presentación — finance-web¶
| Tema | Tecnología |
|---|---|
| Framework | Next.js 15 (App Router) + React 19 |
| Auth cliente | MSAL (@azure/msal-browser / msal-react) |
| i18n | ES / EN (messages.ts) |
| Hosting | Container App, puerto 3000 |
| BFF | Rutas app/api/finance/[...path] → APIM |
Comportamiento de acceso:
- Sin sesión →
LoginPortal - Sesión sin grupo User/Reviewer →
AccessDenied - Con User o Reviewer → workbench
- HITL: botones solo si el access token trae grupo Reviewer
4.2 API — finance-api¶
| Tema | Tecnología |
|---|---|
| Runtime | Python / FastAPI |
| Persistencia | SQLAlchemy → Azure SQL |
| Reglas | Paquete rule-engine (FIN-001…005) |
| Authz | JWT Entra (PyJWT + JWKS) + middleware User|Reviewer |
| HITL | require_reviewer en approve/reject/return |
| Chat | Guardrails + Foundry agent + tools REST |
Endpoints principales (OpenAPI en repo shared/contracts/openapi/finance.yaml):
POST /api/finance/invoices/uploadPOST /api/finance/invoices/{id}/processPOST …/approve|reject|returnGET …/document,…/auditPOST /api/finance/chatGET /api/platform/health
4.3 Gateway — Azure API Management¶
Policy inbound (orden):
- Rate limit por IP (120/min) — anti-flood antes del JWT
- validate-jwt — token Entra válido (audience API)
- validate-jwt + groups — claim
groupsdebe incluir User o Reviewer (403 si no) - HITL — en POST
…/approve|reject|returnexige grupo Reviewer - Rate limit por
sub(300/min) - x-correlation-id
- Backend = FQDN del Container App API
SKU: Developer · VNet: None (público).
4.4 Borde Container Apps (API)¶
| Control | Detalle |
|---|---|
external_enabled |
true (obligatorio sin VNet para que APIM alcance el API) |
| IP allowlist | Solo IP pública de APIM (68.155.193.213/32) |
| Efecto | GET directo al FQDN ACA → 403; vía APIM → OK |
Futuro enterprise: VNet en CAE + APIM en red → entonces external_enabled=false.
4.5 Identidad — Microsoft Entra ID¶
| Artefacto | Rol |
|---|---|
| App SPA (web) | Login MSAL, redirect al FQDN del portal (+ localhost) |
| App API | Audience api://…, scopes access_as_user |
groupMembershipClaims=SecurityGroup |
El access token incluye groups |
Grupo Finance.User |
Acceso de lectura al portal/API |
Grupo Finance.Reviewer |
+ decisiones HITL |
4.6 Datos y AI¶
flowchart LR
PDF[PDF] --> BLOB[Blob invoices]
BLOB --> API[finance-api]
API --> DI[Document Intelligence]
DI --> API
API --> RE[Rule Engine]
RE --> SQL[(Azure SQL)]
API --> SQL
API --> AG[Foundry Agent]
AG -->|tools| API
| Servicio | Uso |
|---|---|
| Blob | Almacenamiento PDF |
| Document Intelligence | Extracción de campos de factura |
| Azure SQL | Suppliers, POs, invoices, reglas, audit, HITL |
| Foundry Agent | Conversación + function tools hacia la API |
| MCP suppliers | Validación proveedor (opcional / paralelo) |
4.7 Observabilidad y alarmas¶
| Pieza | Función |
|---|---|
| Application Insights | Telemetría apps (connection string en ACA) |
| Log Analytics | Workspace detrás de App Insights + CAE |
Action Group ag-eai-dev-ops |
Email ops |
| Metric alerts | ACA RestartCount / CPU · APIM FailedRequests / Capacity · SQL cpu/storage % |
Definición IaC: infra/environments/dev/monitoring.tf.
4.8 CI/CD — Azure DevOps¶
| Pipeline | Qué hace |
|---|---|
eai-terraform-dev |
Plan/apply infra (ManualValidation) |
eai-finance-api-deploy |
az acr build + update ACA con tag BuildId |
eai-finance-web-deploy |
Igual para el portal |
| Templates DevSecOps | SCA, container scan, IaC scan, DAST ZAP |
| Template SonarQube | Análisis + coverage (Cobertura/lcov) |
Lección operativa: actualizar ACA solo con tag :dev no fuerza revisión nueva → se despliega con tag inmutable $(Build.BuildId).
Rama de deploy: deployment.
4.9 Calidad — SonarQube¶
| Proyecto Sonar | Código |
|---|---|
enterprise-ai-finance-api |
services/finance-api |
enterprise-ai-finance-web |
apps/finance-web |
- Extension SonarQube Server en ADO
- Variable group
eai-sonarqube - Coverage: pytest-cov (API) · vitest (Web)
- Pendiente: US 146 (tasks de smells / complejidad)
4.10 Seguridad en pipelines (DevSecOps)¶
Controles típicos del template (no bloquean demo DEV por defecto según flags):
- Python: Bandit, pip-audit
- Containers: Trivy
- Terraform: Checkov
- DAST: OWASP ZAP baseline (post-deploy API)
- Artefactos:
security-reports*
5. Secuencia de una petición autenticada¶
sequenceDiagram
participant U as Usuario
participant W as finance-web
participant E as Entra
participant G as APIM
participant A as finance-api
participant S as SQL/Blob/DI
U->>W: Abrir portal
W->>E: MSAL login
E-->>W: Tokens
U->>W: Acción (lista / process / HITL)
W->>W: Proxy /api/finance/*
W->>G: HTTPS + Bearer + x-correlation-id
G->>G: rate IP → JWT → groups User|Reviewer
alt HITL decide
G->>G: groups debe incluir Reviewer
end
G->>A: Forward (desde IP APIM)
A->>A: Middleware member + ReviewerDep si aplica
A->>S: Datos / DI / reglas
S-->>A: Resultado
A-->>W: JSON
W-->>U: UI
6. Matriz de confianza (quién confía en quién)¶
| Desde | Hacia | Mecanismo |
|---|---|---|
| Browser | Web ACA | HTTPS público |
| Web | APIM | HTTPS + Bearer usuario |
| APIM | API ACA | HTTPS + allowlist IP origen APIM |
| API | SQL / Blob / DI | Managed Identity / connection config |
| API | Foundry | Endpoint proyecto + identidad |
| ADO pipelines | ACR / ACA | Service connection sc-azure-eai-dev |
| Sonar | ADO | Token + extension |
7. Decisiones de arquitectura (ADR resumidos)¶
| Decisión | Elección | Por qué |
|---|---|---|
| Gateway | APIM | Políticas JWT, rate limit, claims, un solo borde |
| Compute | Container Apps | PaaS simple para API/Web sin AKS |
| Reglas | Motor determinístico | Auditable; no dejar políticas críticas solo al LLM |
| Agente | Foundry + tools | Chat acotado; tools = APIs propias |
| Authz | Grupos Entra en JWT | Producto (User vs Reviewer) sin inventar IdP |
| API interna | IP allowlist hoy | Sin VNet, external=false rompería APIM público |
| Deploy | Pipelines + tag build | Evitar revisiones ACA “pegadas” a :dev |
Más contexto: decisions.md · architecture.md
8. Límites actuales (conocerlos evita sorpresas)¶
| Límite | Impacto |
|---|---|
| APIM Developer + sin VNet | Gateway público; no hay red privada |
| CAE sin VNet / sin NAT | Egress ACA no estable → no ip-filter “solo web→APIM” fiable |
| SKU Developer APIM | Capacidad baja; alertas de Capacity importan |
| Group overage en JWT | Si hay demasiados grupos, falla cerrado (403) |
| Stakeholder en ADO | No ve repos (código) |
9. Mapa repo → runtime¶
| Carpeta / artefacto | Destino |
|---|---|
apps/finance-web |
Imagen eai-finance-web → ACA web |
services/finance-api |
Imagen eai-finance-api → ACA api |
services/rule-engine |
Importado por la API |
services/mcp-suppliers-server |
ACA MCP |
infra/environments/dev/*.tf |
RG, SQL, ACA, APIM, Monitor… |
infra/.../policies/apim-finance-api-policy.xml |
Policy APIM |
pipelines/templates/* |
Sonar + security |
agents/finance-agent |
Instructions Foundry |
shared/contracts/openapi |
Contrato API / import APIM |
10. URLs y comandos útiles (DEV)¶
Portal (AFD): https://ep-finance-dev-gfayg5axbhd7h5hf.z02.azurefd.net/
Wiki (AFD): https://ep-docs-dev-hhg4hpa5ecajdhfm.z02.azurefd.net/
APIM: https://apim-eai-dev-fz1d.azure-api.net
Dev Portal: https://apim-eai-dev-fz1d.developer.azure-api.net
API ACA: https://ca-eai-finance-api-dev.… (bloqueado salvo IP APIM)
Health vía APIM: /api/platform/health (requiere JWT + grupo)
Detalle del borde: edge-front-door.md.
11. Próximos bloques técnicos recomendados¶
- OTel → App Insights — traza portal → APIM → API → DI/SQL
- FinOps tokens — costo por chat/process
- Sonar US 146 — bajar smells/complejidad
- VNet + private ingress — APIM y ACA en red; API
external_enabled=false - Vertical HR — Search + MCP HR + HR Web (mismo patrón de borde)
12. Cómo explicar esto en 60 segundos¶
El usuario entra al portal con Entra. El portal Next habla solo con APIM. APIM valida el JWT, exige pertenecer a Finance.User o Reviewer, limita abuso, y solo deja decidir al Reviewer. El API en Container Apps no es alcanzable desde Internet salvo desde la IP de APIM. Dentro, SQL, Blob y Document Intelligence alimentan un motor de reglas; Foundry asiste con tools. Todo se despliega desde Azure DevOps, se mide con App Insights/Monitor y se analiza con SonarQube.
Documento de arquitectura tecnológica · Azure-oriented · Enterprise AI Platform Finance DEV.
Siguiente paso¶
Validar el flujo con el guion de demo. Para identidad y políticas: entra-apim-finance.md.