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 DigitalOcean0f811faa-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