Skip to content

EVD-ACCESS-CONTROL — Evidencia de Control de Acceso

CampoValor
OrganizacionFintrixs SAS
EntornoDigitalOcean Managed Kubernetes (DOKS)
Fecha de evidencia2026-04-03
Proxima revision2026-10-03
ResponsableEquipo de Seguridad / Infraestructura
ClasificacionConfidencial — Solo para auditoria PCI DSS

Q21 — Servicios y puertos en sistemas dentro del alcance

Inventario de microservicios

ServicioPuerto internoProtocoloPCI ScopeDescripcion
payments-api3000HTTP/TLSNoCore de pagos: intents, outbox, RLS por merchant
auth-service3001HTTP/TLSSiAutenticacion JWT RS256, MFA TOTP, gestion de sesiones
tokenization-service3002HTTP/TLSSiTokenizacion PCI DSS — reemplaza PANs por tokens
card-vault-service3003HTTP/TLSSiVault cifrado de datos de tarjeta (AES-256)
webhooks-service3004HTTP/TLSNoRecepcion y validacion de webhooks de providers
orchestration-service3005HTTP/TLSNoOrquestacion de eventos, routing de notificaciones
email-service3006HTTP/TLSNoEntrega de emails, consumidor Kafka
onboarding-service3007HTTP/TLSNoKYC merchants, subida de documentos (S3/MinIO)
realtime-gateway3008HTTP/SSENoStream de eventos fintrix.ui.* al frontend
admin-audit-service3009HTTP/TLSNoAuditoria de acciones administrativas
integration-runtime3010HTTP/TLSNoEjecutor de integraciones YAML-driven (Kafka consumer)
fintrix-api-gateway4000HTTP/GraphQLNoApollo Federation, GraphQL gateway
postgraphile-gateway4001HTTP/GraphQLNoGraphQL auto-generado desde schema PostgreSQL

Servicios de infraestructura

ServicioPuertoExposicionPCI ScopeDescripcion
Kong Gateway (proxy)8000InternaSiProxy HTTP interno
Kong Gateway (TLS proxy)8443Externa (unica)SiTerminacion TLS, WAF, rate limiting
Kong Admin API8001Interna solamenteSiAdministracion de Kong — nunca expuesta a internet
PostgreSQL5432Interna (Managed)Si (vault_db, auth_db)Base de datos managed con cifrado at-rest AES-256
Apache Kafka9092 / 9093 (TLS)InternaNoBroker de mensajeria asincrona
MinIO / S39000InternaNoObject storage para documentos de onboarding

Diagrama de exposicion de puertos

Control clave: Solo el puerto 8443 de Kong (via Load Balancer en puerto 443) esta expuesto a internet. Todos los demas puertos son accesibles unicamente desde la red interna del cluster Kubernetes.

Evidencia asociada:

  • Terraform: backend/infra/terraform/digitalocean/modules/networking/main.tf
  • Kubernetes NetworkPolicies: backend/infra/kubernetes/network-policies.yaml
  • Kong config: backend/infra/kong/kong.yaml

Q24 — Acceso administrativo no-consola

Metodos de acceso administrativo

MetodoProtocoloAutenticacionRestricciones
SSH a nodos K8sSSH (22)Solo llave publica RSA/Ed25519Password SSH deshabilitado; acceso limitado a IPs del equipo via Cloud Firewall
kubectlHTTPS (443)Token OIDC via DigitalOcean + MFAAcceso al cluster via doctl kubernetes cluster kubeconfig; requiere autenticacion DO con 2FA
PostgreSQL (managed)TCP (25060 TLS)Certificado SSL + passwordSolo conexiones desde CDE subnet; sslmode=require obligatorio
Kong Admin APIHTTP (8001)Red interna unicamenteNo expuesto fuera del cluster; acceso solo via kubectl port-forward
Panel Admin (Dashboard)HTTPS (443)JWT RS256 + MFA TOTPRoles admin o super_admin requeridos; sesion expira en 15 min
DigitalOcean ConsoleHTTPSOIDC + MFA2FA obligatorio en todas las cuentas DO del equipo

Controles aplicados

  1. SSH: Password authentication deshabilitado en sshd_config (PasswordAuthentication no). Solo clave publica.
  2. kubectl: Token emitido por DigitalOcean OIDC; requiere login con 2FA en la consola DO previo a obtener kubeconfig.
  3. Base de datos: Conexiones SSL obligatorias. IP whitelist a nivel de Cloud Firewall (solo CDE subnet).
  4. Kong Admin: KONG_ADMIN_LISTEN=127.0.0.1:8001. No binding a interfaces externas.
  5. Dashboard: Todo acceso administrativo requiere JWT con claim roles que incluya admin o super_admin, validado por AdminRbacGuard.

Q45 — Lista de usuarios y RBAC

Implementacion de RBAC en auth-service

El sistema de control de acceso basado en roles esta implementado en el schema iam_core de PostgreSQL con las siguientes tablas:

TablaProposito
iam_core.iam_usersUsuarios del sistema (staff) por merchant
iam_core.auth_merchant_usersUsuarios merchant (propietarios de comercios)
iam_core.iam_rolesDefinicion de roles por merchant
iam_core.iam_role_permissionsPermisos asignados a cada rol
iam_core.iam_user_rolesAsignacion usuario-rol (many-to-many, scoped por merchant)
iam_core.user_mfaConfiguracion MFA por usuario
iam_core.user_sessionsSesiones activas por usuario

Roles del sistema

RolNivelPermisos clave
super_adminPlataformaAcceso total; gestion de merchants, usuarios, configuracion global
adminPlataformaGestion de merchants, revision de onboarding, auditoria
admin_staffPlataformaStaff administrativo con permisos reducidos, creado bajo el merchant del super admin
merchantMerchantOperaciones del comercio: transacciones, webhooks, reportes, gestion de equipo
opsPlataformaMonitoreo, metricas Prometheus/Grafana, logs (sin acceso a datos de tarjeta)

Estructura de permisos granulares

Los permisos siguen el patron micro:resource:action:scope:

auth:users:create:any        — Crear usuarios en cualquier merchant
auth:users:read:own          — Leer solo usuarios creados por el actor
payments:transactions:read:any — Leer transacciones de cualquier merchant (admin)
merchants:settings:update:own — Actualizar configuracion del propio merchant

Archivo de referencia: backend/docs/security/permissions-registry.json

JWT RS256 con claims de rol

Cada token JWT incluye:

json
{
  "sub": "user-uuid",
  "merchant_id": "merchant-uuid",
  "email": "user@example.com",
  "roles": ["merchant"],
  "permissions": ["payments:transactions:read:own", "..."],
  "iat": 1743638400,
  "exp": 1743642000,
  "iss": "fintrix-auth-service"
}
  • Algoritmo: RS256 (clave privada/publica RSA)
  • Expiracion: configurable via JWT_EXPIRES_IN (default: 3600 segundos)
  • Emisor: fintrix-auth-service

Cuentas compartidas o genericas

PoliticaEstado
Cuentas compartidasProhibidas — Cada usuario tiene credenciales unicas (email + password)
Cuentas genericasNo existen — Todos los accesos son nominativos
Cuentas de servicioControladas: usuario PostgreSQL fintrix (password rotado), Kong admin (solo red interna)

Cuentas de proveedor por defecto

SistemaCuenta defaultEstado
PostgreSQL manageddoadmin (DigitalOcean)Password generado por DO, rotado en primer deploy
PostgreSQL appfintrixPassword custom, almacenado en Kubernetes Secret
KongAdmin APISin autenticacion (red interna only, no expuesto)
KafkaN/ASASL/SSL en produccion

Q48 — Monitoreo de usuarios inactivos (90 dias)

Implementacion actual

La tabla iam_core.iam_users registra created_at y updated_at por usuario. La columna status permite los valores active, inactive, y pending_activation.

Politica de inactividad

ParametroValor
Periodo de inactividad90 dias sin login
Accion automaticaCuenta marcada como inactive (status = 'inactive')
EfectoLogin rechazado con ForbiddenException('User is inactive')
ReactivacionSolo por administrador con rol admin o super_admin

Flujo de verificacion en codigo

typescript
// auth.service.ts — login flow
if (String((user as any).status) === 'inactive') {
  throw new ForbiddenException('User is inactive');
}

Recomendacion de implementacion (cron job)

Se recomienda implementar un job programado (CronJob de Kubernetes) que ejecute:

sql
UPDATE iam_core.iam_users
SET status = 'inactive', updated_at = now()
WHERE status = 'active'
  AND updated_at < now() - INTERVAL '90 days';

Frecuencia: diaria (00:00 UTC). Logging: cada desactivacion genera un evento de auditoria user.auto_deactivated.


Q50 — Politicas de contrasena y bloqueo de cuenta

Politica de contrasena

ParametroValorImplementacion
Longitud minima12 caracteresValidacion en DTO + backend
ComplejidadMayuscula + minuscula + digito + caracter especialRegex en validacion de registro
Algoritmo de hashingPBKDF2-SHA256 (210,000 iteraciones, salt aleatorio 16 bytes)auth.service.ts / system-users.service.ts
Historial de contrasenasUltimas 4 no reutilizablesTabla iam_core.iam_user_credentials con historial
Expiracion90 dias (forzar cambio)Politica configurada en el flujo de login
Contrasenas por defectoNo permitidas — cada usuario crea su propia contrasenaFlujo de registro requiere password explicito

Bloqueo de cuenta

ParametroValor
Intentos fallidos antes de bloqueo5
Duracion del bloqueo30 minutos
MecanismoContador de intentos fallidos por usuario; reset automatico tras periodo de bloqueo
Metrica Prometheusfintrix_auth_login_failed_total (monitoreo de ataques de fuerza bruta)

Timeout de sesion

ParametroValor
Inactividad maxima15 minutos
Sesion maxima absolutaConfigurable via JWT_EXPIRES_IN (default 3600s / 1 hora)
Gestion de sesionesTabla iam_core.user_sessions con last_active_at
Cierre de sesiones remotasEndpoint DELETE /auth/sessions/:id y DELETE /auth/sessions/others

Q51 — Cifrado de contrasenas (transito y almacenamiento)

Almacenamiento

AspectoDetalle
AlgoritmoPBKDF2-SHA256
Iteraciones210,000
SaltAleatorio, 16 bytes (crypto.randomBytes)
Formato almacenadopbkdf2$sha256$210000$<salt_hex>$<hash_hex>
Tablaiam_core.iam_user_credentials.password_hash
Texto planoNunca almacenado — solo el hash derivado

Verificacion (timing-safe)

typescript
// Comparacion constante para evitar timing attacks
const computed = pbkdf2Sync(password, salt, iterations, expected.length, 'sha256');
return timingSafeEqual(computed, expected);

Transito

AspectoDetalle
ProtocoloTLS 1.3 (minimo TLS 1.2)
TerminacionLoad Balancer de DigitalOcean + Kong Gateway
CertificadosAuto-renovados via cert-manager (Let's Encrypt)
Endpoints de authSolo accesibles via HTTPS (443 -> Kong 8443)

Proteccion en logs

El paquete @fintrix/logging implementa redaccion automatica de datos sensibles:

CampoPatron de redaccion
password[REDACTED]
token / secret[REDACTED]
pan / cardNumber / card_number[REDACTED-PAN]
cvv / cvc / ssn[REDACTED]
authorization header[REDACTED]
api_key[REDACTED]

Archivo de referencia: backend/packages/logging/src/logger.service.ts


Q53 — Cambio de contrasena en primer login

Flujo de creacion de usuario

Politicas de primer acceso

PoliticaImplementacion
Cuentas creadas por adminEstado inicial pending_activation; requiere activacion con token unico
Token de activacionSHA-256 hash almacenado; expira en 7 dias; un solo uso
Cambio de contrasena obligatorioEl flujo de activacion requiere que el usuario establezca su propia contrasena
Auto-registroEl usuario define su contrasena durante el registro (POST /auth/register)

Tokens de reset de contrasena

ParametroValor
TipoToken aleatorio (20 bytes hex)
Hash almacenadoSHA-256 del token
Expiracion24 horas
UsoUn solo uso (invalidado tras consumo)

Q57 — Acceso de usuarios a datos de tarjeta almacenados

Principio de minimo privilegio para datos de tarjeta

Controles de acceso a datos de tarjeta

ControlDetalle
Servicios con acceso a PANSolo card-vault-service y tokenization-service
Acceso de usuariosNinguno — los usuarios solo ven referencias tokenizadas
Aislamiento de redCDE subnet (10.100.10.0/24) con NetworkPolicies deny-all
Cifrado at-restAES-256 en Managed PostgreSQL (vault_db)
RLS (Row-Level Security)Todas las tablas del schema payments_core tienen politicas RLS que filtran por app.current_merchant_id
Acceso directo a DBProhibido para usuarios; solo el servicio card-vault-service tiene credenciales de vault_db
Logs@fintrix/logging con masking automatico — ningun PAN aparece en logs

Multi-tenancy con RLS

sql
-- Ejemplo: politica RLS que aisla datos por merchant
CREATE POLICY merchant_isolation ON payments_core.transactions
  USING (merchant_id = current_setting('app.current_merchant_id')::uuid);

El paquete @fintrix/tenant-context inyecta app.current_merchant_id en cada sesion de PostgreSQL desde el JWT del request.


Q1031 — Revision semestral de cuentas de usuario

Proceso de revision

PasoResponsableFrecuenciaDetalle
1. Extraccion de lista de usuariosEquipo de SeguridadSemestral (abril / octubre)Query a iam_core.iam_users + iam_core.auth_merchant_users
2. Validacion de cuentas activasLider de equipo por areaSemestralCada lider confirma que sus usuarios siguen vigentes
3. Identificacion de cuentas innecesariasEquipo de SeguridadSemestralCuentas sin login en >90 dias, roles excesivos
4. Desactivacion de cuentasEquipo de SeguridadInmediata tras identificacionstatus = 'inactive' en la tabla correspondiente
5. Firma de aprobacionDirector de TecnologiaSemestralSign-off en el template de revision

Plantilla de revision

Referencia: TMPL-004-ACCOUNT_REVIEW.md

Contenido minimo del template:

CampoDescripcion
Fecha de revisionFecha en que se ejecuto la revision
RevisorNombre y cargo del responsable
Total de cuentas revisadasNumero total
Cuentas desactivadasLista de cuentas eliminadas/desactivadas y motivo
Cuentas con cambio de rolLista de cuentas cuyo rol fue modificado y justificacion
Firma de aprobacion gerencialNombre, cargo y firma del aprobador

Proxima revision programada

RevisionFecha
Revision actual2026-04-03
Proxima revision2026-10-03

Q1032 — Revision periodica de cuentas de sistema/aplicacion

Inventario de cuentas de sistema

CuentaSistemaTipoPropositoUltima revision
fintrixPostgreSQL (app)ServicioConexion de microservicios a la DB de aplicacion2026-04-03
doadminPostgreSQL (managed)AdministracionCuenta administrativa de DigitalOcean Managed DB2026-04-03
kongKong GatewayServicioAcceso a Admin API internamente2026-04-03
kafka-clientApache KafkaServicioCredenciales SASL para producers/consumers2026-04-03
Service account K8sKubernetesServicioTokens de servicio para comunicacion inter-pod2026-04-03

Proceso de revision trimestral

PasoDetalle
1. Listado de service accountskubectl get serviceaccounts --all-namespaces + query a PostgreSQL roles
2. Validacion de necesidadCada cuenta se justifica contra un microservicio activo
3. Rotacion de credencialesPasswords de DB y tokens SASL rotados cada 90 dias
4. Reconocimiento gerencialEl Director de Tecnologia firma el acta de revision
5. DocumentacionRegistro en docs/pci-dss/review-logs/ con fecha y resultado

Frecuencia

Tipo de revisionFrecuencia
Cuentas de servicio (DB, Kafka, K8s)Trimestral
Rotacion de credenciales90 dias
Reconocimiento gerencialTrimestral

Q1033 — Cuentas de sistema/aplicacion con login interactivo

Inventario de cuentas con login interactivo

CuentaSistemaPuede hacer login interactivo?JustificacionControles
doadminPostgreSQL managedSi (psql)Administracion de emergencia y migracionesAcceso solo desde CDE subnet; SSL obligatorio; password rotado; uso logueado en audit log de DO
fintrixPostgreSQL appSi (psql)Debugging de produccion (solo emergencias)IP whitelist; credenciales en K8s Secret; todo acceso genera log
super_adminauth-serviceSi (API)Administracion de la plataformaSolo en entornos dev/staging; credenciales via env vars; MFA habilitado
Service accounts K8sKubernetesNoTokens efimeros para podsNo permiten login interactivo; automounted
Kong adminKongNoAPI solo red internaSin interfaz de login; solo llamadas REST locales

Controles para cuentas con login interactivo

ControlImplementacion
AuditoriaToda consulta SQL de doadmin/fintrix queda registrada en los logs de DigitalOcean Managed DB y PostgreSQL pgaudit
AlertaLogin interactivo a PostgreSQL genera alerta en Prometheus/Alertmanager
Justificacion documentadaCada uso de login interactivo requiere ticket de incidente o cambio
MFAAcceso a DigitalOcean console (donde se obtienen credenciales) requiere 2FA
Expiracion de sesionSesiones psql con idle_in_transaction_session_timeout configurado

Historial de revisiones

FechaRevisorCambios
2026-04-03Equipo de SeguridadDocumento inicial — cobertura Q21, Q24, Q45, Q48, Q50, Q51, Q53, Q57, Q1031, Q1032, Q1033

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