Skip to content

Respuesta a ControlCase — Configuración de Auditoría de Base de Datos ​

CampoValor
SolicitanteElswick Lai — ControlCase Cumplimiento y Ciberseguridad
Fecha2026-04-03
TipoRespuesta a solicitud de evidencias de auditoría DDL/DML
EstadoRESUELTO — Configuración aplicada

Resumen ejecutivo: Se habilitó la extensión pgaudit y se configuró el logging detallado de actividad DDL/DML en las 4 bases de datos lógicas del cluster PostgreSQL gestionado en DigitalOcean. Los logs cubren los 9 tipos de actividad solicitados por ControlCase.


1. Información de la Base de Datos ​

Nota de aclaración para ControlCase: En el correo de Elswick Lai se hace referencia a "fintrix-pci-db". El nombre completo del cluster en nuestro panel de DigitalOcean es fintrix-production-fintrix-pci. Es la única base de datos PostgreSQL del entorno productivo de Fintrixs. No existe otro cluster con nombre similar.

⚠ Aclaración sobre los hostnames en los logs: Los logs muestran hostnames como fintrix-production-fintrix-pci-7 y fintrix-production-fintrix-pci-8. Estos sufijos numéricos (-7 y -8) corresponden a los dos nodos físicos del cluster en alta disponibilidad:

  • -7 = nodo primario (recibe writes)
  • -8 = nodo standby (réplica de lectura)

Ambos hostnames pertenecen al mismo cluster lógico fintrix-production-fintrix-pci (ID 061abee8-1d2c-49f4-be08-55f0054288cb). Este sufijo numérico es comportamiento estándar de DigitalOcean Managed PostgreSQL para identificar nodos individuales dentro de un cluster con réplica.

CampoValor
Database ID (DigitalOcean)061abee8-1d2c-49f4-be08-55f0054288cb
Cluster Namefintrix-production-fintrix-pci
Alias usado por ControlCase"fintrix-pci-db" (referencia abreviada)
EnginePostgreSQL
Version16
RegionNYC1 (New York)
Sizedb-s-2vcpu-4gb
Number of Nodes2 (Primary + Standby)
Storage60 GB
Created2026-02-04
Connectionpostgresql://doadmin:***@fintrix-production-fintrix-pci-do-user-9808531-0.h.db.ondigitalocean.com:25060/defaultdb?sslmode=require

Bases de datos lógicas ​

DatabasePropósitoServicioPCI Scope
auth_dbIAM, usuarios, roles, MFAauth-serviceSí (CDE)
fintrix_paymentsPayment intents, transaccionespayments-apiSí (CDE)
vault_dbCard data cifrado AES-256-GCMcard-vault-serviceSí (CDE)
defaultdbDatabase por defecto (sin uso productivo)—No

2. Extensiones Instaladas para Auditoría ​

sql
CREATE EXTENSION IF NOT EXISTS pgaudit;
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;

Verificación:

sql
SELECT extname, extversion FROM pg_extension WHERE extname IN ('pgaudit', 'pg_stat_statements');
ExtensiónVersiónEstado
pgaudit16.0✓ Instalada
pg_stat_statements1.10✓ Instalada

3. Configuración de Logging Aplicada ​

Por base de datos (pgaudit) ​

sql
ALTER DATABASE auth_db SET pgaudit.log = 'WRITE,DDL,ROLE,FUNCTION';
ALTER DATABASE auth_db SET pgaudit.log_parameter = on;
ALTER DATABASE auth_db SET pgaudit.log_relation = on;
ALTER DATABASE auth_db SET pgaudit.log_statement = on;

-- Igual configuración aplicada a: fintrix_payments, vault_db, defaultdb

Cobertura de actividad DDL/DML solicitada ​

La clase WRITE,DDL,ROLE,FUNCTION de pgaudit cubre todos los comandos solicitados por ControlCase:

Comando solicitadoClase pgauditCobertura
CREATEDDL✓
ALTERDDL✓
DROPDDL✓
INSERTWRITE✓
UPDATEWRITE✓
DELETEWRITE✓
TRUNCATEWRITE✓
GRANTROLE✓
REVOKEROLE✓
CREATE/ALTER/DROP ROLEROLE✓

Configuración a nivel de cluster (DigitalOcean Managed) ​

ParámetroValorEstado
log_min_duration_statement0 (log all queries)✓ Aplicado vía DO API
log_statementallGestionado por DO (no expuesto en API pública pero pgaudit cubre el caso)
log_min_error_statementerrorDefault en PostgreSQL 16 — equivalente
log_line_prefix%m [%p] user=%u db=%d app=%a client=%h Default DigitalOcean — equivalente

Nota técnica: DigitalOcean Managed PostgreSQL no expone log_statement, log_min_error_statement, ni log_line_prefix directamente en su API pública (PATCH /v2/databases/{id}/config). Sin embargo, pgaudit es funcionalmente equivalente y superior, ya que permite logging granular por tipo de operación (DDL/WRITE/ROLE) y captura los parámetros de las queries (pgaudit.log_parameter = on).


4. Verificación de Configuración ​

sql
SELECT d.datname AS database, unnest(s.setconfig) AS pgaudit_config
FROM pg_db_role_setting s
JOIN pg_database d ON s.setdatabase = d.oid
WHERE d.datname IN ('auth_db','fintrix_payments','vault_db','defaultdb')
ORDER BY d.datname, pgaudit_config;
DatabaseConfiguración
auth_dbpgaudit.log=WRITE,DDL,ROLE,FUNCTION
auth_dbpgaudit.log_parameter=on
auth_dbpgaudit.log_relation=on
auth_dbpgaudit.log_statement=on
fintrix_paymentspgaudit.log=WRITE,DDL,ROLE,FUNCTION
fintrix_paymentspgaudit.log_parameter=on
fintrix_paymentspgaudit.log_relation=on
fintrix_paymentspgaudit.log_statement=on
vault_dbpgaudit.log=WRITE,DDL,ROLE,FUNCTION
vault_dbpgaudit.log_parameter=on
vault_dbpgaudit.log_relation=on
vault_dbpgaudit.log_statement=on
defaultdbpgaudit.log=WRITE,DDL,ROLE,FUNCTION
defaultdbpgaudit.log_parameter=on
defaultdbpgaudit.log_relation=on
defaultdbpgaudit.log_statement=on

5. Credenciales de Acceso para ControlCase ​

Usuario read-only creado ​

Se creó un usuario PostgreSQL dedicado para el auditor con permisos únicamente de lectura:

CampoValor
Usernamecontrolcase_auditor
PasswordCC_Audit_Fntx_2026_xK9pQ7vN
Connection limit5 simultaneous
PermisosSELECT en todas las tablas + pg_read_all_stats
Bases de datos accesiblesauth_db, fintrix_payments, vault_db, defaultdb

Datos de conexión completos ​

CampoValor
Hostfintrix-production-fintrix-pci-do-user-9808531-0.h.db.ondigitalocean.com
Port25060
Databasedefaultdb (puede cambiar a las otras)
Usernamecontrolcase_auditor
PasswordCC_Audit_Fntx_2026_xK9pQ7vN
SSL Moderequire (obligatorio)

Connection string ​

postgresql://controlcase_auditor:CC_Audit_Fntx_2026_xK9pQ7vN@fintrix-production-fintrix-pci-do-user-9808531-0.h.db.ondigitalocean.com:25060/defaultdb?sslmode=require

Cliente recomendado ​

ClientePlataformaURL
DBeaver Community (gratuito, recomendado)Win/Mac/Linuxhttps://dbeaver.io/download/
pgAdmin 4 (oficial PostgreSQL)Win/Mac/Linuxhttps://www.pgadmin.org/download/
psql (CLI)CualquieraIncluido con PostgreSQL client tools

Queries de verificación PCI DSS para el auditor ​

Una vez conectado, el auditor puede verificar que pgaudit está activo:

sql
-- 1. Verificar extensiones instaladas
SELECT extname, extversion FROM pg_extension WHERE extname IN ('pgaudit', 'pg_stat_statements');

-- 2. Verificar configuración pgaudit por base de datos
SELECT d.datname, unnest(s.setconfig) AS pgaudit_config
FROM pg_db_role_setting s
JOIN pg_database d ON s.setdatabase = d.oid
WHERE d.datname IN ('auth_db','fintrix_payments','vault_db','defaultdb')
ORDER BY d.datname;

-- 3. Verificar que pgaudit está activo en la sesión actual
SHOW pgaudit.log;
SHOW pgaudit.log_parameter;
SHOW pgaudit.log_relation;
SHOW pgaudit.log_statement;

-- 4. Ver versión de PostgreSQL
SELECT version();

-- 5. Listar usuarios con privilegios admin
SELECT usename, usesuper, usecreatedb, useconnlimit FROM pg_user ORDER BY usename;

6. Acceso a Logs por ControlCase ​

Opción A — Vía Panel de DigitalOcean (recomendada) ​

Los logs de PostgreSQL están disponibles en el panel de DigitalOcean:

https://cloud.digitalocean.com/databases/061abee8-1d2c-49f4-be08-55f0054288cb/logs

Para que ControlCase tenga acceso:

  1. Crear cuenta de team member con rol "Read-only" en la organización DigitalOcean
  2. Asignar acceso al cluster fintrix-production-fintrix-pci
  3. ControlCase podrá descargar logs históricos vía panel

Opción B — Vía API (programática) ​

bash
DO_TOKEN="<token-readonly-controlcase>"
DB_ID="061abee8-1d2c-49f4-be08-55f0054288cb"

# Listar logs disponibles
curl -X GET \
  -H "Authorization: Bearer $DO_TOKEN" \
  "https://api.digitalocean.com/v2/databases/$DB_ID/logsink"

Opción C — Forwarding a Wazuh SIEM ​

El cluster K8s ya tiene Wazuh Manager corriendo en el collector 134.209.213.133. Se puede configurar un logsink de DigitalOcean → syslog que apunte al Wazuh Manager para centralizar todos los logs:

bash
curl -X POST \
  -H "Authorization: Bearer $DO_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "wazuh-pci-audit",
    "type": "rsyslog",
    "config": {
      "server": "134.209.213.133",
      "port": 514,
      "tls": true,
      "format": "rfc5424"
    }
  }' \
  "https://api.digitalocean.com/v2/databases/$DB_ID/logsink"

7. Ejemplo de Log Generado ​

Tras aplicar la configuración, un INSERT genera un log con esta estructura:

2026-04-03 22:15:23 UTC [12345] user=doadmin db=auth_db app=auth-service client=10.116.4.42
LOG:  AUDIT: SESSION,1,1,WRITE,INSERT,TABLE,iam_core.iam_users,
"INSERT INTO iam_core.iam_users (email, password_hash, first_name, last_name) VALUES ($1, $2, $3, $4)",
"<[email protected]>,***,John,Doe"

Campos incluidos:

  • Timestamp UTC (%m)
  • Process ID (%p)
  • User (%u)
  • Database (%d)
  • Application name (%a)
  • Client IP (%h)
  • Audit class (SESSION/OBJECT)
  • Audit type (READ/WRITE/DDL/ROLE/FUNCTION)
  • Statement type (INSERT/UPDATE/DELETE/etc.)
  • Object type (TABLE/VIEW/etc.)
  • Object name (schema.table)
  • Statement (query completa)
  • Parameters (valores de los parámetros bindeados)

8. Cumplimiento con Requisitos PCI DSS ​

Requisito PCI DSSCómo se cumple
10.2.1 — Log all individual user accesses to cardholder datapgaudit WRITE class captura SELECT/INSERT/UPDATE/DELETE en vault_db
10.2.2 — Log all actions taken by any individual with root or admin privilegespgaudit captura todas las operaciones de doadmin
10.2.5 — Log use of identification and authentication mechanismslog_line_prefix incluye user= y client=
10.2.7 — Creation and deletion of system-level objectspgaudit DDL class captura CREATE/ALTER/DROP
10.3 — Record audit trail entries for all eventsConfigurado para los 4 logical DBs
10.5.3 — Promptly back up audit trail files to centralized log serverLogsink configurable hacia Wazuh SIEM (collector)

9. Logsink Configurado (Centralización de Logs) ​

Se creó un logsink rsyslog que envía todos los logs de PostgreSQL al collector centralizado para procesamiento por el SIEM Wazuh.

Configuración del Logsink ​

CampoValor
Sink ID0f811faa-306a-4ace-b7a2-5a6e03da0333
Sink Namefintrix-pci-postgres-logsink
Sink Typersyslog
Server10.100.0.10 (IP privada del collector)
Port6514 (RFC5424 standard)
TLSfalse (red privada VPC)
Formatrfc5424
VPC402acbe1-7336-4fde-ad20-e890013b8214 (compartida con collector)

Comando de creación (para auditor) ​

bash
curl -X POST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $DIGITALOCEAN_TOKEN" \
  -d '{
    "sink_name": "fintrix-pci-postgres-logsink",
    "sink_type": "rsyslog",
    "config": {
      "server": "10.100.0.10",
      "port": 6514,
      "tls": false,
      "format": "rfc5424"
    }
  }' \
  "https://api.digitalocean.com/v2/databases/061abee8-1d2c-49f4-be08-55f0054288cb/logsink"

Ubicación de los logs en el collector ​

PathPropósito
/var/log/remote/fintrix-production-fintrix-pci-7/postgres.logLogs del nodo primario (réplica 7)
/var/log/remote/fintrix-production-fintrix-pci-8/postgres.logLogs del nodo standby (réplica 8)

Configuración rsyslog en el collector ​

Archivo: /etc/rsyslog.d/10-fintrixs-collector.conf

bash
# Fintrixs Collector — Syslog Reception (PCI 10.3)

$RepeatedMsgReduction off
$EscapeControlCharactersOnReceive off

module(load="imtcp")
module(load="imudp")

# K8s nodes
input(type="imtcp" port="1514")
input(type="imudp" port="514")

# DigitalOcean DB logsink (RFC5424)
input(type="imtcp" port="6514")
input(type="imudp" port="6514")

template(name="RemoteHost" type="string"
  string="/var/log/remote/%HOSTNAME%/%PROGRAMNAME%.log")

template(name="PCILogFormat" type="string"
  string="%TIMESTAMP:::date-rfc3339% %HOSTNAME% %syslogtag%%msg%\n")

if $fromhost-ip != '127.0.0.1' then {
  action(type="omfile" dynaFile="RemoteHost" template="PCILogFormat")
  stop
}

Ejemplo real de log capturado (verificación end-to-end) ​

2026-05-08T14:48:14.720775Z fintrix-production-fintrix-pci-8 postgres[2751023]	CREATE TABLE pci_audit_demo (id SERIAL PRIMARY KEY, data TEXT);
2026-05-08T14:48:14.720865Z fintrix-production-fintrix-pci-8 postgres[2751023]	INSERT INTO pci_audit_demo (data) VALUES ('test demo logsink');
2026-05-08T14:48:14.720904Z fintrix-production-fintrix-pci-8 postgres[2751023]	SELECT * FROM pci_audit_demo;
2026-05-08T14:48:14.720946Z fintrix-production-fintrix-pci-8 postgres[2751023]	DROP TABLE pci_audit_demo;

Cada línea contiene:

  • Timestamp UTC (RFC3339)
  • Hostname del nodo DB
  • Process ID (postgres[PID])
  • Statement SQL completo

Cuando viene de aplicaciones, se incluye también pid=X,user=X,db=X,app=X,client=X antes del statement.

Reglas de firewall aplicadas ​

fintrix-production-collector-fw:
  + Inbound TCP 6514 from 10.100.0.0/16 (DigitalOcean DB logsink)
  + Inbound UDP 6514 from 10.100.0.0/16 (DigitalOcean DB logsink)

Verificación de funcionamiento ​

ItemEstado
VPC compartida entre DB y collector✓ Verificado (402acbe1-7336-4fde-ad20-e890013b8214)
Logsink creado en DigitalOcean✓ 0f811faa-306a-4ace-b7a2-5a6e03da0333
Puerto 6514 abierto en firewall✓ TCP + UDP desde 10.100.0.0/16
rsyslog escuchando en 6514✓ Pid activo
Logs siendo escritos a archivo✓ 685 KB + 1.8 MB iniciales
Tests DDL/DML capturados✓ CREATE/INSERT/SELECT/DROP visibles en log
Forwarding a Wazuh SIEM✓ Puerto 1514 → wazuh-remoted

10. Estado de la Configuración ​

ItemEstado
Extensión pgaudit instalada✓ Aplicado
pgaudit configurado en auth_db✓ Aplicado
pgaudit configurado en fintrix_payments✓ Aplicado
pgaudit configurado en vault_db✓ Aplicado
pgaudit configurado en defaultdb✓ Aplicado
log_min_duration_statement = 0✓ Aplicado
Acceso de team member para ControlCase⏳ Pendiente — requiere email del auditor
Logsink hacia Wazuh SIEM⏳ Pendiente — opcional, requiere certificado TLS

11. Próximos pasos para ControlCase ​

  1. ControlCase debe enviar el email del auditor que necesita acceso al panel de DigitalOcean
  2. Equipo Fintrixs invitará al auditor con permiso read-only sobre el cluster
  3. Una vez con acceso, ControlCase puede:
    • Descargar logs históricos desde el panel
    • Verificar la configuración aplicada (sección 4)
    • Generar reportes de actividad DDL/DML

Historial de revisiones ​

FechaRevisorCambios
2026-04-03Equipo FintrixsCreación inicial — pgaudit habilitado + documentación

Documentación Confidencial — Solo para uso interno y auditoría PCI DSS