La base de datos va a estar en subnets privadas.
Escucho alguna versión de esta frase en muchos reviews de arquitectura.
Suena responsable. Se ve bien en el diagrama. La base de datos está dentro de una VPC, la subnet tiene la etiqueta private y no hay ninguna flecha que venga desde Internet.
El diagrama parece completo, así que podríamos terminar el review aquí. Pero “es privada” debería ser solamente el inicio de la conversación.
¿Cómo investiga un developer un problema en non-prod? ¿Cómo aplica CI/CD una migración de esquema o un hotfix? ¿Cómo creamos y revocamos usuarios de la base de datos? ¿De dónde viene el acceso de emergencia cuando el camino normal no funciona?
Privado es el estado inicial, no el diseño terminado
Las aplicaciones necesitan leer y escribir datos. Los pipelines necesitan desplegar cambios. Los developers necesitan feedback mientras construyen features (e incluso cierta flexibilidad para innovar). Los operadores necesitan diagnosticar fallos. Un sistema útil siempre tendrá caminos de acceso; la arquitectura decide si esos caminos son intencionales o improvisados.
Por lo tanto, el objetivo no es hacer que sea imposible llegar a un recurso. Es que sea accesible solo para el actor correcto, en el contexto correcto, con los permisos correctos y durante el tiempo necesario.
A eso me refiero con: Privado por defecto, accesible por diseño.
Privado no significa oculto. Significa restringido, pero la conversación suele terminar antes de que alguien defina esas restricciones.
Ya usamos credenciales de base de datos, identidades cloud, llaves de Git, API keys, usuarios y contraseñas para restringir el acceso. En este contexto, privado significa que no existe acceso anónimo o implícito. No significa que no exista ningún acceso.
Una subnet privada solo responde la pregunta de routing
Una subnet privada normalmente significa que sus recursos no tienen una ruta directa desde Internet. Todavía pueden tener salida a Internet mediante NAT y pueden ser alcanzables desde muchas otras redes conectadas a la VPC.
Esa configuración solo responde una pregunta: ¿Puede el tráfico llegar hasta ahí desde el punto X?
No nos dice quién inició la petición, qué puede hacer después de conectarse, cuánto debe durar su acceso o si podremos explicar sus acciones más adelante.
Un firewall puede permitir una conexión al puerto 5432. No puede decidir si quien se conecta debería ejecutar DROP TABLE, leer datos de clientes o crear un usuario. Una VPN puede colocar a un empleado dentro de una red conectada, pero no convierte a todos los empleados en administradores autorizados de la base de datos.
La red es un filtro importante, pero no es un proveedor de identidad.
Un modelo de acceso debería agregar cuatro elementos al alcance de red:
- Identidad: cada persona y workload se autentica como sí misma.
- Autorización: esa identidad recibe únicamente las acciones y los datos que necesita.
- Contexto y tiempo: el ambiente, origen, aprobación y expiración limitan el acceso.
- Auditabilidad: las conexiones y acciones sensibles dejan evidencia.
Llamar privado a un recurso sin definir estos controles es confundir su ubicación en la red con su seguridad.
Cómo se ve esto en una base de datos
Para una base de datos de producción, el punto de partida suele ser sencillo: no tener un endpoint público, usar subnets privadas en múltiples availability zones, cifrar los datos en tránsito y en reposo, y utilizar reglas de entrada que referencien security groups aprobados en vez de rangos CIDR demasiado amplios.
El resto del diseño se vuelve más claro cuando describimos explícitamente a cada actor:
| Actor | Camino de acceso | Identidad y autoridad |
|---|---|---|
| Aplicación | Conexión desde el runtime del servicio hacia su base de datos | Identidad del servicio; solo su esquema y las operaciones que necesita |
| Developer | Sesión intermediada hacia una base de datos de non-prod | Identidad SSO vinculada a un rol limitado de base de datos; la sesión expira |
| Deployment job | Job efímero lanzado dentro de la red de destino | Identidad federada del pipeline; permiso para migraciones y nada más |
| Operador | Sesión just-in-time aprobada mediante un proxy de acceso | Rol de administrador nominal que expira; se auditan la conexión y las consultas |
| Operador de emergencia | Camino separado de break glass, probado antes de una emergencia | Rol elevado temporal; alerta inmediata y revisión obligatoria después de usarlo |
Las herramientas exactas pueden cambiar. Lo importante es que cada camino lleve una identidad y termine en un rol de base de datos creado para ese propósito. Tener acceso a la red no otorga autoridad dentro de la base de datos.
Esto es especialmente importante para los developers. “Pídele a alguien que abra temporalmente el security group” no es un diseño de acceso. Non-prod puede ofrecer un camino conveniente y self-service sin volver el acceso anónimo o permanente. Producción puede exigir una aprobación más estricta sin depender de una contraseña de administrador compartida.
Todos estos caminos deberían existir antes de un incidente.
CI/CD también es un actor
Los diagramas de arquitectura suelen mostrar el tráfico entre la aplicación y la base de datos, pero olvidan por completo el pipeline.
Si solamente se puede llegar a la base de datos desde el runtime de la aplicación, eventualmente los equipos inventan otra ruta: una credencial de larga duración en el sistema de CI, un script ejecutado desde una laptop o una regla de security group que nadie recuerda cerrar.
CI/CD necesita las dos partes del modelo de acceso: un camino de red controlado y una identidad propia autenticada. El camino puede venir de un runner dentro de la VPC, una red de runners conectada o un deployment job lanzado dentro del ambiente de destino. La identidad puede utilizar federación OIDC y un rol cloud temporal en lugar de una access key estática.
Para los cambios de base de datos, prefiero migraciones versionadas ejecutadas como un deployment job dedicado. El job entra mediante un camino aprobado, asume una identidad específica para migraciones, obtiene credenciales temporales, aplica el cambio esperado, genera logs y termina.
La aplicación no debería necesitar permisos de owner porque existen migraciones. El pipeline no debería recibir acceso ilimitado porque el deployment está automatizado.
La administración de usuarios puede seguir el mismo patrón: un workflow administrativo asume un rol de alcance limitado y se ejecuta desde un ambiente controlado. Los ingenieros no necesitan conectividad permanente ni una contraseña maestra compartida solamente para crear, rotar o revocar un usuario.
S3 cambia el mecanismo, no el modelo
S3 no vive dentro de nuestras subnets privadas de la misma manera que una base de datos, pero el mismo modelo de acceso sigue aplicando.
Block Public Access establece el estado inicial. Las bucket policies y IAM definen qué operaciones puede realizar cada identidad. Las condiciones de un VPC endpoint pueden limitar el contexto de red. KMS controla quién puede descifrar los datos. Los access logs conservan la evidencia.
Cuando una persona o un sistema externo realmente necesita un objeto, una pre-signed URL de corta duración puede ser el diseño correcto. No vuelve público al bucket; otorga una capacidad limitada a una operación y un periodo específico.
Esa es la diferencia: el acceso público está disponible para todos; el acceso diseñado es explícito.
Los reviews de arquitectura necesitan caminos, no etiquetas
Cuando alguien dice “la base de datos es privada”, la siguiente versión del diagrama debería mostrar algo más que los colores de las subnets. Para cada aplicación, persona, pipeline o sistema externo, el review debería poder responder:
- ¿Por qué camino de red se conecta este actor?
- ¿Cómo se autentica sin un secreto compartido de larga duración?
- ¿Cuál es la autoridad mínima que recibe?
- ¿Qué contexto se requiere y cuándo expira el acceso?
- ¿Cómo se otorga, audita y revoca?
- ¿Cuál es el camino controlado cuando el normal no está disponible?
- ¿Qué ocurre si una credencial se ve comprometida?
Si el diseño no puede responder estas preguntas, el recurso no es privado de forma segura. Solamente es difícil de alcanzar.
El diseño real comienza después de “privado”
Los sistemas difíciles crean caminos no oficiales. Las personas comparten credenciales, ejecutan cambios desde sus laptops, dejan túneles abiertos y solicitan permisos más amplios de lo necesario. La accesibilidad no es lo opuesto a la seguridad; un camino bien diseñado suele ser lo que evita que las personas la ignoren.
La red reduce la superficie de ataque. La identidad nos dice quién cruza el límite. La autorización restringe lo que puede hacer. El contexto y la expiración contienen el riesgo. La auditoría hace que el resultado sea explicable. Ninguno de estos controles reemplaza a los demás; juntos convierten un recurso privado en un sistema operable.
Privado por defecto nos da una base segura. Accesible por diseño ofrece a las aplicaciones, developers, pipelines y operadores un camino intencional para atravesarla. Juntos hacen que el camino seguro sea también el más sencillo, incluso cuando producción está en llamas.
“La base de datos está en subnets privadas” es un buen punto de partida. Significa que el diseño ha comenzado, no que está terminado.
Una buena arquitectura no elimina el acceso. Lo hace deliberado, limitado, temporal y explicable.