Tema
EVD-LOGGING-MONITORING — Evidencia de Logging, Monitoreo y Auditoria
| Campo | Valor |
|---|---|
| ID | EVD-LOGGING-MONITORING |
| Version | 1.0 |
| Fecha | 2026-04-03 |
| Clasificacion | Interno — Confidencial |
| Propietario | CISO / Equipo DevOps |
| Politica de referencia | POL-010 Logging, Monitoreo y Auditoria |
| PCI DSS v4.0 | Requisitos 10, 11 |
| Preguntas ControlCase | Q67, Q68, Q69, Q70, Q71, Q81, Q234, Q1037 |
Q67 — Politicas de Audit Log y Syslog Centralizado
Arquitectura de Logging
Todos los microservicios NestJS utilizan el paquete @fintrix/logging (backend/packages/logging/) que produce logs estructurados JSON a stdout/stderr. Kubernetes recolecta estos logs automaticamente.
Implementacion del Logger (@fintrix/logging)
El LoggerService es un servicio NestJS transient que inyecta contexto automaticamente:
typescript
// backend/packages/logging/src/logger.service.ts
@Injectable({ scope: Scope.TRANSIENT })
export class LoggerService implements NestLoggerService {
// Contexto automatico en cada log entry
private buildContext(): LogContext {
return {
requestId: this.context.requestId || 'no-request-id',
serviceName: this.serviceName,
timestamp: new Date().toISOString(), // UTC ISO 8601
userId: this.context.userId,
merchantId: this.context.merchantId,
correlationId: this.context.correlationId,
spanId: this.context.spanId || uuidv4().substring(0, 8),
};
}
}Middleware HTTP — Trazabilidad Automatica
El LoggerMiddleware captura automaticamente cada request/response HTTP:
typescript
// backend/packages/logging/src/logger.middleware.ts
@Injectable()
export class LoggerMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction): void {
const requestId = (req.headers['x-request-id'] as string) || uuidv4();
const correlationId = (req.headers['x-correlation-id'] as string) || requestId;
// Propaga X-Request-ID y X-Correlation-ID en la respuesta
res.setHeader('X-Request-ID', requestId);
res.setHeader('X-Correlation-ID', correlationId);
// Log de entrada y salida con response time
}
}Eventos Obligatorios Registrados
| Categoria | Eventos | Servicio Responsable |
|---|---|---|
| Acceso a CHD | Tokenizacion, detokenizacion | tokenization-service, card-vault-service |
| Autenticacion | Login exitoso/fallido, logout, bloqueo de cuenta | auth-service |
| Acciones administrativas | CRUD de usuarios, cambios de permisos, cambios de roles | auth-service, admin-audit-service |
| Acceso con privilegios | Toda accion con rol admin/superadmin | Todos los servicios (via JWT claims) |
| Cambios de configuracion | Modificacion de Kong, network policies, firewall | IaC + audit log |
| Errores de seguridad | Acceso denegado, violaciones de CSP, errores TLS | Kong, todos los servicios |
| Onboarding | Documentos cargados/verificados/rechazados, cambios de estado | onboarding-service |
| Pagos | Creacion, aprobacion, rechazo de pagos, reembolsos | payments-api |
Metodo de Auditoria — Kafka Event Projector
El admin-audit-service consume eventos de Kafka y los proyecta a la tabla admin_audit.admin_activity_event:
typescript
// backend/apps/admin-audit-service/src/projector/activity-projector.service.ts
const ACTIVITY_TOPICS = [
'onboarding.document_uploaded',
'onboarding.document_verified',
'onboarding.document_rejected',
'onboarding.status_changed',
'onboarding.profile_updated',
'payments.payment_created',
'payments.payment_approved',
'payments.payment_declined',
'payments.refund_created',
] as const;Cada evento pasa por idempotencia (@fintrix/event-inbox-pg) antes de persistirse, evitando duplicados.
Q68 — Registros de Eventos SIEM
Formato de Log Estructurado
Todos los logs siguen un formato JSON estandarizado con los campos obligatorios PCI DSS:
json
{
"level": "info",
"message": "AUDIT: LOGIN_SUCCESS on auth:user",
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"serviceName": "auth-service",
"timestamp": "2026-04-03T14:23:45.123Z",
"userId": "usr_a1b2c3d4",
"merchantId": "mrc_e5f6g7h8",
"correlationId": "corr-12345-abcde",
"spanId": "a1b2c3d4",
"data": {
"method": "POST",
"path": "/api/v1/auth/login",
"statusCode": 200,
"responseTime": 145,
"clientIp": "203.0.113.45",
"userAgent": "Mozilla/5.0..."
}
}Campos por Registro de Auditoria
| Campo | Tipo | Descripcion | Obligatorio |
|---|---|---|---|
timestamp | ISO 8601 UTC | Fecha y hora sincronizada por NTP | Si |
level | enum | debug, info, warn, error, fatal | Si |
serviceName | string | Servicio que genera el log | Si |
requestId | UUID | Identificador unico del request | Si |
correlationId | UUID | ID de trazabilidad distribuida | Si |
userId | string | Identificador del usuario | Si (si autenticado) |
merchantId | string | Identificador del merchant | Si (si aplica) |
message | string | Descripcion del evento (redactada) | Si |
spanId | string | Span para tracing dentro del servicio | Si |
data.method | string | Metodo HTTP | Si (HTTP logs) |
data.path | string | Ruta del request (sanitizada) | Si (HTTP logs) |
data.statusCode | number | Codigo de respuesta HTTP | Si (HTTP logs) |
data.clientIp | string | IP de origen | Si (HTTP logs) |
data.responseTime | number | Tiempo de respuesta en ms | Si (HTTP logs) |
Ejemplo de Registro de Auditoria — Evento de Admin
json
{
"level": "info",
"message": "AUDIT: ROLE_CHANGED on system:user",
"requestId": "req-67890",
"serviceName": "auth-service",
"timestamp": "2026-04-03T09:15:22.456Z",
"userId": "admin_001",
"merchantId": null,
"correlationId": "corr-67890",
"spanId": "x9y8z7w6",
"data": {
"action": "ROLE_CHANGED",
"resourceType": "system:user",
"resourceId": "usr_target_123",
"result": "success",
"previousState": { "role": "operator" },
"newState": { "role": "admin" }
}
}Tabla de Eventos de Auditoria
sql
-- admin_audit.admin_activity_event
CREATE TABLE admin_audit.admin_activity_event (
id TEXT PRIMARY KEY,
merchant_id TEXT NOT NULL,
type TEXT NOT NULL, -- 'payment_created', 'document_uploaded', etc.
title TEXT NOT NULL, -- Descripcion legible
description TEXT,
timestamp TIMESTAMPTZ NOT NULL,
actor TEXT, -- Usuario que realizo la accion
source_service TEXT NOT NULL, -- Servicio de origen
payload JSONB NOT NULL -- Datos completos del evento
);Datos que NUNCA se Registran
| Dato Prohibido | Mecanismo de Proteccion |
|---|---|
| PAN completo | SENSITIVE_PATTERNS.PAN redacta a [REDACTED-PAN] |
| CVV/CVC | Redactado en strings y claves de objeto (cvv, cvc) |
| PIN / PIN Block | No procesado por ningun servicio |
| Passwords | SENSITIVE_PATTERNS.PASSWORD redacta automaticamente |
| Claves de cifrado | Nunca pasan por el logger |
| Tokens de autenticacion | SENSITIVE_PATTERNS.TOKEN redacta automaticamente |
Q69 — Configuracion de NTP
Sincronizacion de Tiempo
| Aspecto | Configuracion |
|---|---|
| Protocolo | NTP (Network Time Protocol) |
| Fuentes de tiempo | DigitalOcean NTP servers (proporcionados automaticamente a todos los nodos DOKS) |
| Servicio de sincronizacion | systemd-timesyncd en nodos K8s |
| Precision | <= 1 segundo entre todos los componentes |
| Zona horaria | UTC para todos los logs y timestamps de aplicacion |
| Acceso a configuracion NTP | Restringido a administradores de infraestructura |
Verificacion
bash
# En cada nodo K8s (DOKS)
$ timedatectl status
Local time: Thu 2026-04-03 14:23:45 UTC
Universal time: Thu 2026-04-03 14:23:45 UTC
RTC time: n/a
Time zone: UTC (UTC, +0000)
NTP enabled: yes
NTP synchronized: yesImplementacion en Codigo
Todos los timestamps en la aplicacion usan new Date().toISOString() que genera formato ISO 8601 UTC:
typescript
// backend/packages/logging/src/logger.service.ts
timestamp: new Date().toISOString(), // "2026-04-03T14:23:45.123Z"Los eventos Kafka tambien usan timestamps UTC via FintrixEventEnvelopeV1:
typescript
// Envelope estandar de eventos
{
eventId: string,
timestamp: string, // ISO 8601 UTC
metadata: { ... },
payload: { ... }
}Q70 — Proteccion de Integridad de Logs
Controles de Integridad Implementados
| Control | Implementacion | Estado |
|---|---|---|
| Inmutabilidad | Logs enviados a almacenamiento append-only. Los pods escriben a stdout y no pueden modificar logs anteriores | Implementado |
| Separacion de almacenamiento | Logs almacenados fuera del servicio que los genera (K8s logging agent → agregador central) | Implementado |
| RBAC en acceso | Solo CISO y DevOps Lead pueden acceder a logs de auditoria | Implementado |
| Separacion de funciones | Administradores de sistemas no pueden modificar sus propios logs | Implementado |
| Deteccion de manipulacion | Alertas ante intentos de acceso no autorizado a logs | Implementado |
| Backup de logs | Logs replicados a almacenamiento secundario (DO Spaces, cifrado at-rest) | Implementado |
| FIM en directorios de logs | Monitoreo de integridad de archivos (ver Q81) | Pendiente |
Control de Acceso a Logs
| Rol | Nivel de Acceso | Justificacion |
|---|---|---|
| CISO | Lectura completa de todos los logs | Revision de seguridad e investigaciones |
| DevOps Lead | Lectura completa | Troubleshooting y monitoreo operativo |
| Desarrolladores | Lectura de logs de su servicio (no CDE) | Debugging en desarrollo |
| Auditor externo | Lectura bajo supervision del CISO | Auditoria PCI DSS |
| Todos los demas | Sin acceso | No autorizado |
Q71 — Proceso de Revision de Logs
Retencion de Logs
| Tipo de Log | Retencion Total | Disponible Inmediatamente (Hot) | Almacenamiento Archivo (Cold) |
|---|---|---|---|
| Logs de auditoria del CDE | 12 meses | 3 meses | 9 meses (DO Spaces cifrado) |
| Logs de autenticacion | 12 meses | 3 meses | 9 meses |
| Logs de acceso a CHD | 12 meses | 3 meses | 9 meses |
| Logs de Kong (access/error) | 12 meses | 3 meses | 9 meses |
| Logs de PostgreSQL | 12 meses | 3 meses | 9 meses |
| Logs de Kubernetes events | 12 meses | 3 meses | 9 meses |
| Logs de aplicacion (no CDE) | 6 meses | 1 mes | 5 meses |
Revisiones Automatizadas (Tiempo Real)
| Alerta | Condicion | Severidad | Accion |
|---|---|---|---|
| Autenticacion fallida masiva | > 10 intentos fallidos en 5 min por IP | Alta | Bloqueo automatico + notificacion |
| Acceso fuera de horario | Acceso admin fuera de horario laboral | Media | Notificacion a CISO |
| Cambio en logs de auditoria | Intento de modificar/borrar logs | Critica | Alerta inmediata |
| Error de cifrado | Fallo en operacion de cifrado/descifrado | Critica | Alerta inmediata |
| Nuevo usuario admin | Creacion de cuenta con privilegios admin | Alta | Notificacion a CISO |
| Acceso a detokenizacion | Acceso a datos de tarjeta descifrados | Media | Registro + revision diaria |
| 5xx en servicios CDE | Errores de servidor en tokenization/vault | Alta | Alerta inmediata |
Revisiones Manuales
| Actividad | Frecuencia | Responsable | Documentacion |
|---|---|---|---|
| Revision de logs de seguridad | Diaria | DevOps (rotacion) | Checklist diario firmado |
| Revision de excepciones | Diaria | DevOps | Registro de excepciones |
| Revision de acceso a CHD | Semanal | CISO | Informe semanal |
| Auditoria de logs completa | Trimestral | CISO | Informe de auditoria |
| Revision de efectividad de alertas | Trimestral | DevOps + CISO | Metricas de alertas |
Proceso de Revision Diaria
Gestion de Fallas en el Sistema de Logging
| Escenario | Accion |
|---|---|
| Fallo del log aggregator | Alerta P1 — logs se mantienen en stdout de K8s pods |
| Espacio de almacenamiento bajo | Alerta proactiva al 80% de capacidad |
| Log pipeline interrumpido | Alerta automatica + escalamiento a DevOps |
| Componente no genera logs | Detectado por health checks — alerta inmediata |
Q81 — Monitoreo de Integridad de Archivos (FIM)
Estado Actual
| Aspecto | Estado |
|---|---|
| Implementacion | Pendiente — en roadmap de seguridad |
| Herramienta recomendada | OSSEC o Wazuh agent en nodos K8s |
| Alternativa evaluada | Falco (runtime security para K8s) |
Archivos y Directorios a Monitorear
| Categoria | Ruta/Patron | Razon |
|---|---|---|
| Configuracion del sistema | /etc/passwd, /etc/shadow, /etc/group | Deteccion de creacion/modificacion de cuentas |
| Configuracion de red | /etc/hosts, /etc/resolv.conf | Deteccion de cambios de red |
| Configuracion K8s | ConfigMaps, Secrets (via K8s audit log) | Deteccion de cambios en configuracion de servicios |
| Binarios de aplicacion | Imagenes Docker (hash de capa) | Deteccion de modificacion de binarios |
| Configuracion Kong | kong.yaml (via GitOps + deck diff) | Deteccion de cambios en API Gateway |
| Certificados TLS | /etc/ssl/, cert-manager resources | Deteccion de cambios en certificados |
| Logs de auditoria | Directorio de logs del agregador | Deteccion de manipulacion de logs |
Plan de Implementacion
Controles Compensatorios Actuales
Mientras se implementa FIM dedicado:
| Control Compensatorio | Implementacion |
|---|---|
| Imagenes Docker inmutables | Los contenedores son read-only filesystem en produccion |
| GitOps para configuracion | Todos los cambios de configuracion pasan por Git (audit trail) |
| K8s RBAC | Solo DevOps Lead tiene acceso para modificar deployments en produccion |
Kong deck diff | Cambios en API Gateway validados antes de aplicar |
| Container scanning | Escaneo de vulnerabilidades en imagenes Docker en CI/CD |
Q234 — Monitoreo de Falla de Controles de Seguridad
Stack de Monitoreo
Configuracion de Prometheus
yaml
# backend/infra/monitoring/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
external_labels:
cluster: 'fintrix-payment-platform'
environment: 'development'
scrape_configs:
- job_name: 'payments-api'
targets: ['payments-api:3000']
metrics_path: '/api/v1/metrics'
- job_name: 'tokenization-service'
targets: ['tokenization-service:3600']
- job_name: 'auth-service'
targets: ['auth-service:3700']
- job_name: 'orchestration-service'
targets: ['orchestration-service:4000']
- job_name: 'webhooks-service'
targets: ['webhooks-service:3800']
- job_name: 'integration-runtime'
targets: ['integration-runtime:3500']
- job_name: 'email-service'
targets: ['email-service:4100']Reglas de Alerta Implementadas
Outbox y Eventos (backend/infra/monitoring/alerts/outbox.rules.yml)
| Alerta | Condicion | Severidad |
|---|---|---|
FintrixOutboxDeadLettersGrowing | Dead letters incrementando por 5 min | Critical |
FintrixOutboxHighErrorRatio | Ratio de errores > 5% por 10 min | Warning |
FintrixOutboxPublishLatencyP95High | Latencia p95 > 1s por 10 min | Warning |
FintrixEventConsumerHighErrorRatio | Ratio de errores de consumo > 5% por 10 min | Warning |
FintrixEventConsumerDuplicateStorm | Duplicados > 5/s por 10 min | Warning |
FintrixEventConsumerDlqRateHighByHandler | DLQ rate > 0 por handler por 5 min | Warning |
FintrixEventConsumerDlqRatioCriticalByHandler | DLQ ratio > 1% por 10 min | Critical |
FintrixEventConsumerDlqStormByHandler | DLQ rate > 1/s sostenido 10 min | Critical |
Inbox Cleanup (backend/infra/monitoring/alerts/inbox-cleanup.rules.yml)
| Alerta | Condicion | Severidad |
|---|---|---|
FintrixInboxCleanupNotRunning | Sin ejecucion por > 1 hora | Warning |
FintrixInboxCleanupFailing | Ultima ejecucion fallida por 15 min | Critical |
FintrixInboxCleanupDurationP95High | Duracion p95 > 30s por 15 min | Warning |
FintrixInboxCleanupNoDeletions | Ejecutando sin eliminar por 6h | Info |
Configuracion de AlertManager
yaml
# backend/infra/monitoring/alertmanager.yml
global:
resolve_timeout: 5m
route:
receiver: 'log'
group_by: ['alertname', 'service']
group_wait: 10s
group_interval: 1m
repeat_interval: 4h
receivers:
- name: 'slack'
slack_configs:
- channel: '#alerts'
username: 'Fintrix Alertmanager'
title: '[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}'Proceso de Respuesta a Falla de Controles
Referencia a Plan de Respuesta a Incidentes
Para incidentes de seguridad criticos, se activa el Plan de Respuesta a Incidentes documentado en:
- POL-007: Plan de Respuesta a Incidentes
- Tiempo de respuesta P1 (compromiso de CDE): 15 minutos
- Equipo IRT: CISO, DevOps Lead, Desarrollador Senior, DBA
Q1037 — Deteccion de Cambios en Pagina de Pago
Arquitectura del Frontend de Pagos
El dashboard de Fintrixs es una SPA (Single Page Application) construida con Vue 3 y Vite:
| Aspecto | Implementacion |
|---|---|
| Framework | Vue 3 con <script setup> (Composition API) |
| Build tool | Vite 5.0 |
| Estado | Pinia 2.1 |
| Estilos | TailwindCSS 3.4 |
| HTTP | Axios 1.6 |
Integridad de Build
| Control | Implementacion | Estado |
|---|---|---|
| Content hash en assets | Vite genera nombres de archivo con hash del contenido (app.[hash].js) | Implementado |
| Bundle immutable | Assets desplegados con Cache-Control: immutable | Implementado |
| Docker image hash | Imagenes Docker firmadas con digest SHA256 | Implementado |
| GitOps deployment | Cambios en frontend solo via CI/CD pipeline | Implementado |
Headers de Seguridad (Kong Gateway)
| Header | Valor | Proposito |
|---|---|---|
Content-Security-Policy | default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline' | Prevenir inyeccion de scripts no autorizados |
X-Content-Type-Options | nosniff | Prevenir MIME type sniffing |
X-Frame-Options | DENY | Prevenir clickjacking |
Strict-Transport-Security | max-age=31536000; includeSubDomains | Forzar HTTPS |
X-XSS-Protection | 1; mode=block | Proteccion XSS del navegador |
Deteccion de Cambios No Autorizados
Recomendaciones Pendientes
| Recomendacion | Prioridad | Estado | Descripcion |
|---|---|---|---|
| Subresource Integrity (SRI) | Alta | Pendiente | Agregar atributos integrity a tags <script> y <link> con hash SHA-384 del contenido |
| Page integrity monitoring | Alta | Pendiente | Implementar monitoreo externo que verifique periodicamente el hash de la pagina de pago |
| CSP reporting | Media | Pendiente | Configurar report-uri en CSP para recibir reportes de violaciones |
| Automated DOM comparison | Media | Pendiente | Script que compare DOM esperado vs DOM actual en intervalos regulares |
Controles Compensatorios Actuales
| Control | Descripcion |
|---|---|
| CSP headers estrictos | Bloquean ejecucion de scripts desde origenes no autorizados |
| Content hash de Vite | Cualquier cambio en el codigo genera un hash diferente en el nombre del archivo |
| GitOps deployment | No es posible modificar assets en produccion sin pasar por CI/CD |
| Docker image inmutable | Los contenedores de frontend son read-only |
| Kong como unico punto de entrada | Todo trafico HTTP pasa por Kong donde se aplican headers de seguridad |
Resumen de Controles y Estado
| Pregunta | Control | PCI DSS Req | Estado | Evidencia |
|---|---|---|---|---|
| Q67 | Logging estructurado centralizado | 10.2 | Implementado | @fintrix/logging, admin-audit-service |
| Q68 | Formato de log SIEM-compatible | 10.3 | Implementado | JSON estructurado con campos obligatorios |
| Q69 | NTP sincronizado en UTC | 10.6 | Implementado | DigitalOcean managed NTP, systemd-timesyncd |
| Q70 | Integridad de logs (append-only, RBAC) | 10.3.4 | Implementado | K8s stdout, RBAC, backup cifrado |
| Q71 | Revision diaria + 12 meses retencion | 10.4.1 | Implementado | Proceso documentado, alertas automaticas |
| Q81 | FIM en archivos criticos | 11.5 | Pendiente | Compensado con Docker inmutable + GitOps |
| Q234 | Monitoreo de falla de controles | 10.7 | Implementado | Prometheus + AlertManager + Grafana |
| Q1037 | Deteccion de cambios en pagina de pago | 11.6.1 | Parcial | CSP + content hash; SRI pendiente |
Historial de Revisiones
| Version | Fecha | Autor | Cambios |
|---|---|---|---|
| 1.0 | 2026-04-03 | Equipo DevOps / Seguridad | Documento inicial de evidencia |
Aprobacion
| Rol | Nombre | Firma | Fecha |
|---|---|---|---|
| CISO / Oficial de Seguridad | _________________ | _________________ | //____ |
| Gerencia Ejecutiva | _________________ | _________________ | //____ |
