Tema
PCI DSS Pregunta 38 — Separación lógica entre entornos (Production vs Staging)
| Campo | Valor |
|---|---|
| Solicitante | José David Álvarez — QSA ControlCase |
| Comentario QSA | "Por favor proveer pantallazos con las configuraciones de red que confirmen la independencia de ambientes mencionada" |
| Fecha de extracción | 2026-05-27 |
| Tipo de evidencia | VPCs + clusters + DBs separados + test de aislamiento ejecutado |
| Estado | RESUELTO — Staging environment desplegado, separación verificada en runtime |
| Paquete adjunto | q38-env-separation-20260527.tar.gz |
Resumen ejecutivo: Fintrixs separa los entornos
productionystaginga nivel físico de red: 2 VPCs distintos en DigitalOcean (CIDR10.100.0.0/16para prod,10.101.0.0/16para staging), 2 clusters DOKS independientes, 2 bases de datos PostgreSQL Managed separadas, firewalls dedicados por entorno, y trusted sources de DB que rechazan cross-environment connections. Aislamiento verificado en runtime: ping y TCP desde un pod prod (10.100.0.16) hacia un nodo staging (10.101.0.3) resultan en100% packet lossytimeout— DigitalOcean VPCs son redes L2 independientes sin posibilidad de peering. Costo adicional staging: ~$39/mes (1 nodo K8s + DB pequeña + VPC/firewall gratis).
1. Arquitectura de 2 entornos separados
┌───────────────────────────────────────────────────────────────────────────┐
│ PRODUCTION (fintrix-production-*) │
├───────────────────────────────────────────────────────────────────────────┤
│ VPC: fintrix-production-vpc (10.100.0.0/16) │
│ Cluster: fintrix-production-k8s (K8s 1.34.8-do.0, 6 nodes) │
│ Pools: cde-pool + app-pool + system-pool │
│ Database: fintrix-production-fintrix-pci (PG 16, db-s-2vcpu-4gb) │
│ Droplets: collector, cdd, vapt, bitwarden, 6 k8s nodes │
│ Firewalls: fintrix-production-{cde,app,dmz,mgmt,cdd,collector,vapt}-fw │
│ Real data: Cardholder data REAL (PCI scope), merchants, transactions │
└───────────────────────────────────────────────────────────────────────────┘
╳ NO ROUTING — NO PEERING — NO CROSS-VPC TRAFFIC ╳
┌───────────────────────────────────────────────────────────────────────────┐
│ STAGING (fintrix-staging-*) │
├───────────────────────────────────────────────────────────────────────────┤
│ VPC: fintrix-staging-vpc (10.101.0.0/16) │
│ Cluster: fintrix-staging-k8s (K8s 1.34.8-do.0, 1 node) │
│ Pools: staging-pool │
│ Database: fintrix-staging-fintrix-pci (PG 16, db-s-1vcpu-1gb) │
│ Droplets: staging-pool-38lwy4 │
│ Firewalls: fintrix-staging-app-fw + k8s-public-access-97577f4a │
│ Data: Synthetic only (NUNCA cardholder data REAL) │
└───────────────────────────────────────────────────────────────────────────┘
2. VPCs separados (separación de red física)
Listado real
bash
$ doctl vpcs list --format Name,Region,IPRange,ID --no-header | grep fintrix
fintrix-production-vpc nyc1 10.100.0.0/16 402acbe1-7336-4fde-ad20-e890013b8214
fintrix-staging-vpc nyc1 10.101.0.0/16 11e94855-7a24-452f-b648-2600731fd387| VPC | CIDR | ID | Miembros |
|---|---|---|---|
| production | 10.100.0.0/16 | 402acbe1-... | 10 droplets (incl. 6 K8s nodes) |
| staging | 10.101.0.0/16 | 11e94855-... | 1 droplet (staging-pool-38lwy4) |
Característica arquitectónica de DigitalOcean:
- VPCs son redes L2 independientes en backplane privado
- NO existe VPC peering disponible (limitación de DO platform)
- Tráfico cross-VPC SOLO posible vía internet (public IPs + firewall traversal)
- Tráfico intra-VPC fluye por backplane privado de DO (no internet)

Captura directa del panel DigitalOcean — Networking → VPC

Miembros del VPC production

Miembros del VPC staging

3. Clusters K8s y Databases separados
Clusters
bash
$ doctl k8s cluster list --format Name,Region,VersionSlug --no-header
fintrix-production-k8s nyc1 1.34.8-do.0 ← cluster PROD (6 nodes)
fintrix-staging-k8s nyc1 1.34.8-do.0 ← cluster STAGING (1 node)| Production | Staging | |
|---|---|---|
| Nombre | fintrix-production-k8s | fintrix-staging-k8s |
| Cluster ID | a19e81ac-537a-44ed-a228-8010f561a530 | 97577f4a-346a-4008-841f-66dce3b4a921 |
| K8s version | 1.34.8-do.0 | 1.34.8-do.0 (parity) |
| Nodepools | 3 (cde + app + system) | 1 (staging) |
| Nodes | 6 | 1 |
| VPC | fintrix-production-vpc | fintrix-staging-vpc |
Databases
bash
$ doctl databases list --format Name,Engine,Status,Region --no-header
fintrix-production-fintrix-pci pg online nyc1 ← PROD DB
fintrix-staging-fintrix-pci pg online nyc1 ← STAGING DB| Production | Staging | |
|---|---|---|
| Nombre | fintrix-production-fintrix-pci | fintrix-staging-fintrix-pci |
| DB ID | 061abee8-1d2c-49f4-be08-55f0054288cb | 75917799-1bf3-4cc3-85d6-71b9dba38e3d |
| Engine | PostgreSQL 16 | PostgreSQL 16 (parity) |
| Size | db-s-2vcpu-4gb | db-s-1vcpu-1gb |
| Storage | 60 GiB | 10 GiB |
| Data | Cardholder data REAL | Synthetic only |

Captura directa del panel DigitalOcean — Kubernetes
Lista de clusters (ambos visibles en la cuenta)

Cluster production (overview)

Cluster staging (overview)

Captura directa del panel DigitalOcean — Databases

4. DB trusted sources (control crítico)
Cada base de datos permite conexiones solo desde su propio cluster — no cross-environment.
Production DB firewall
$ doctl databases firewalls list 061abee8-... (PROD DB)
UUID Type Value
1cd4c5b2-e1e2-43d4-9f1f-... k8s a19e81ac-...-prod-cluster
4aa82dd4-e7e6-4735-8eac-... ip_addr 10.100.10.0/24 (APP pool)Staging DB firewall
$ doctl databases firewalls list 75917799-... (STAGING DB)
UUID Type Value
6661a809-4bb0-46cb-9514-... k8s 97577f4a-...-staging-clusterResultado: cross-environment access es IMPOSIBLE:
- 🚫 PROD DB rechaza conexiones desde el staging cluster ID (
97577f4a-...) - 🚫 STAGING DB rechaza conexiones desde el prod cluster ID (
a19e81ac-...) - 🚫 Cualquier IP fuera de los trusted sources → connection refused

Captura directa del panel — Trusted Sources de cada DB
Production DB → Settings → Trusted Sources

Staging DB → Settings → Trusted Sources

Observa: la lista de "Trusted Sources" de la PROD DB NO incluye el cluster staging (
97577f4a-...) y la STAGING DB NO incluye el cluster prod (a19e81ac-...). Esto es enforcement técnico cross-environment a nivel de DigitalOcean Managed DBaaS.
5. Test EJECUTADO de aislamiento cross-VPC
Test en vivo desde un pod en producción (cluster fintrix-production-k8s, hostNetwork sobre nodo cde-38q702 = 10.100.0.16) intentando alcanzar el cluster staging (nodo en 10.101.0.3):
bash
$ kubectl run cross-vpc-test --image=nicolaka/netshoot \
--overrides='{spec:{hostNetwork:true,nodeSelector:{kubernetes.io/hostname: cde-38q702}}}'
# Test 1: ICMP ping
$ kubectl exec cross-vpc-test -- ping -c 3 -W 5 10.101.0.3
PING 10.101.0.3 (10.101.0.3) 56(84) bytes of data.
--- 10.101.0.3 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2047ms ← ✓ BLOQUEADO
# Test 2: TCP a puerto 22
$ kubectl exec cross-vpc-test -- timeout 8 nc -zvw 5 10.101.0.3 22
nc: connect to 10.101.0.3 port 22 (tcp) timed out: Operation in progress ← ✓ TIMEOUTConclusión técnica
| Test | Resultado | Interpretación |
|---|---|---|
| Ping ICMP prod→staging | 100% packet loss | Sin ruta en routing table |
| TCP nc :22 prod→staging | Timeout 8s | Sin path L3 entre VPCs |
| DNS staging DB hostname | Resolves (público) | Conexión solo posible via internet+firewall |
DO VPCs son redes L2 independientes en backplane privado; no existe route propagation entre VPCs y la plataforma DO no permite VPC peering. El aislamiento físico está garantizado por la arquitectura de red del cloud provider.

6. Costo y rationale del staging environment
| Recurso | Size | Cost/mes |
|---|---|---|
fintrix-staging-vpc | VPC nyc1 | FREE |
fintrix-staging-k8s (1 nodo) | s-2vcpu-4gb | $24/mes |
fintrix-staging-fintrix-pci | db-s-1vcpu-1gb | $15/mes |
fintrix-staging-app-fw | Cloud Firewall | FREE |
| Egress traffic | ~10 GB/mes | FREE (incluido) |
| TOTAL | ~$39/mes |
Justificación de la inversión
| Razón | Impacto |
|---|---|
| PCI v4 Req 6.5.3 mandata separación prod/pre-prod | Audit-required |
| Evitar "shadow testing" contra producción | Reduce audit findings |
| Smoke/integration tests sin tocar customer data | Mitiga PR risk |
| Pre-prod validation antes de surge upgrade DOKS prod | Reduce production incidents |
| Rollback rehearsals + DR drills sin riesgo a clientes | Build operational muscle |
ROI: 1 incidente PCI evitado >> $39/mes en 12 meses (>$468/año).

7. POL-005 — Reglas de flujo de datos prod ↔ staging
Prohibido absolutamente
| Acción | Por qué |
|---|---|
| ❌ Copiar production DB → staging DB | Contiene cardholder data (PCI Req 6.5.3.b) |
| ❌ Copiar production logs → staging | Pueden contener PII y PAN tokens |
| ❌ Apuntar staging app a production DB | Cross-env DB connection |
| ❌ Hardcoded production credentials en staging | Privilege escalation path |
| ❌ Manual SSH del developer a producción para "quick fixes" | Bypass de SDLC |
Permitido y recomendado
| Acción | Mecanismo |
|---|---|
| ✓ Synthetic data generator para staging | scripts/seed-staging.sh |
| ✓ E2E smoke tests en staging con mock data | GitHub Actions matrix |
| ✓ Integration tests CI desplegados temporalmente | PR-triggered deploy |
| ✓ Performance tests + chaos engineering | Litmus + k6 en staging |
| ✓ Rollback rehearsals con snapshots de staging | doctl databases snapshot |
Controles técnicos que lo enforzan
| Control | Implementación |
|---|---|
| DB trusted sources | Prod DB rechaza staging cluster ID |
| VPC isolation | Sin routes entre 10.100/16 ↔ 10.101/16 |
| Service accounts separados | Prod SA no tiene staging perms |
| Secrets scoping | Production secrets NO existen en staging (Vault) |

8. Cumplimiento PCI DSS Q38 — mapping
| Requisito PCI v4 | Control Fintrixs | Status |
|---|---|---|
| Req 6.5.3.a Pre-prod environments separated from prod | VPC 10.100/16 vs 10.101/16 + clusters + DBs separados | ✅ |
| Req 6.5.3.b Live PANs NOT used in pre-prod | POL-005 + DB trusted sources + synthetic data only | ✅ |
| Req 6.5.3.1 Separation of roles and data | K8s RBAC + DB credentials separados por entorno | ✅ |
| Req 6.5.4 Separate dev/test/prod data | Synthetic seeds en staging, NUNCA copy de prod | ✅ |
| Req 6.4.6 Emergency changes documented | Branch protection + admin override audited | ✅ |

9. Cómo replicar la verificación
bash
# 1. Listar VPCs
doctl vpcs list --format Name,Region,IPRange,ID --no-header | grep fintrix
# 2. Listar clusters
doctl k8s cluster list --format Name,Region,VersionSlug,Status.State --no-header
# 3. Listar databases
doctl databases list --format Name,Engine,Status,Region --no-header
# 4. Trusted sources de cada DB
doctl databases firewalls list <PROD_DB_ID>
doctl databases firewalls list <STAGING_DB_ID>
# 5. Droplets por VPC
doctl compute droplet list --format Name,VPCUUID --no-header | \
awk '$2=="402acbe1-..." {print "PROD:", $1}; $2=="11e94855-..." {print "STAGING:", $1}'
# 6. Test cross-VPC isolation
kubectl run isolation-test --image=nicolaka/netshoot \
--overrides='{"spec":{"hostNetwork":true,"nodeSelector":{...prod node...}}}'
kubectl exec isolation-test -- ping -c 3 <staging-node-private-ip>10. Paquete de evidencia descargable
📥 Descargar evidencia completa (q38-env-separation-20260527.tar.gz)
Contenido:
q38-env-separation/
├── 00-README.txt ← Resumen ejecutivo
├── 01-resource-comparison.txt VPCs + clusters + DBs prod vs staging
├── 02-k8s-clusters.json JSON completo de DOKS clusters
├── 03-databases.json JSON completo de databases
├── 04-vpcs.json JSON completo de VPCs
├── 05-firewalls.json JSON completo de Cloud Firewalls
└── 06-droplets.json Droplets con su VPC assignment11. Conclusión para el QSA
Separación lógica + física verificada: 2 VPCs DigitalOcean en
nyc1con CIDR no-overlapping (10.100/16 prod, 10.101/16 staging), sin posibilidad de peering, sin route propagation.Infraestructura completa duplicada por entorno:
- Cluster K8s separado (
fintrix-production-k8svsfintrix-staging-k8s) - PostgreSQL DB separada (
fintrix-production-fintrix-pcivsfintrix-staging-fintrix-pci) - Firewalls dedicados
- Naming convention clara:
fintrix-{environment}-*
- Cluster K8s separado (
DB trusted sources rechazan cross-environment connections — control técnico verificable vía
doctl databases firewalls list.Test de aislamiento ejecutado en vivo: ping y TCP desde pod prod hacia nodo staging → 100% packet loss + timeout.
POL-005 prohíbe explícitamente copy de production data hacia staging (PCI Req 6.5.3.b satisfecho con control técnico + procedural).
Decisión arquitectónica documentada: staging deployed 2026-05-27 (~$39/mes) como remediation del gap PCI v4 Req 6.5.3.
Evidencia auditable extraída en vivo el 2026-05-27 y empaquetada en el tarball adjunto.
Historial de revisiones
| Fecha | Revisor | Cambios |
|---|---|---|
| 2026-05-27 | Gabriel Ureña (CTO Fintrixs) | Creación inicial — staging environment desplegado, separación de red verificada via cross-VPC isolation test |
