# Regla: Infraestructura Cloud

Esta regla es OBLIGATORIA para todo recurso desplegado en cloud sin excepción.
Una infraestructura mal configurada puede causar brechas de seguridad, pérdida de datos
o costos desbocados en cuestión de horas. Ningún recurso cloud se considera listo para
producción si viola cualquiera de los puntos aquí listados.

---

## Principio de menor privilegio en IAM

Cada identidad (usuario, rol, cuenta de servicio) recibe solo los permisos
estrictamente necesarios para su función, y nada más.

- NUNCA asignar políticas de administrador (`AdministratorAccess`, `Owner`, `*:*`)
  a cuentas de servicio, aplicaciones o usuarios que no sean administradores reales.
- NUNCA asignar permisos de escritura cuando solo se necesita lectura.
- NUNCA asignar permisos a nivel de cuenta/organización cuando el scope correcto
  es un recurso específico (ej: un bucket S3, no todos los buckets).
- Crear roles de IAM específicos por función:
  - Rol para la aplicación web (lectura de secrets, escritura en BD, publicar en cola)
  - Rol para el proceso de backup (lectura de BD, escritura en storage)
  - Rol para el pipeline de CI/CD (push de imágenes, despliegue en el servicio)
  Estos roles son diferentes y tienen permisos diferentes.
- Revisar y limpiar permisos no utilizados cada 90 días.
  AWS tiene `IAM Access Analyzer` para detectar permisos sin uso.
  GCP tiene `IAM Recommender` con el mismo propósito.
- Las llaves de acceso programático (API keys, service account keys) deben
  rotarse cada 90 días máximo. Preferir roles temporales (STS AssumeRole, Workload Identity)
  sobre llaves de larga duración cuando sea posible.
- Autenticación multifactor (MFA) obligatoria para todos los usuarios humanos
  de la consola cloud, sin excepción. Incluyendo administradores.

---

## Cifrado en reposo y en tránsito

Todos los datos deben estar cifrados, tanto almacenados como en movimiento.

### En reposo

- Todos los volúmenes de disco (EBS, Persistent Disk, Managed Disks) deben
  tener cifrado habilitado. Verificar que no está desactivado por defecto.
- Todos los buckets de object storage (S3, GCS, Azure Blob) con cifrado activado.
  Preferir llaves administradas por el cliente (KMS) para datos sensibles.
- Las bases de datos relacionales y NoSQL con cifrado de almacenamiento habilitado.
  RDS: `StorageEncrypted: true`. Cloud SQL: `diskEncryptionConfiguration`.
- Los backups cifrados con la misma llave (o llave separada para mayor aislamiento).
- Los snapshots de volúmenes y AMIs cifrados.

### En tránsito

- TLS 1.2 mínimo. TLS 1.3 preferido. Deshabilitar TLS 1.0 y TLS 1.1 explícitamente.
- HTTPS obligatorio para toda comunicación entre servicios, incluyendo comunicación
  interna entre microservicios dentro de la misma VPC.
- Certificados de TLS renovados automáticamente (ACM, Let's Encrypt con cert-manager,
  Google-managed certificates).
- HSTS habilitado con `max-age` mínimo de 31536000 (1 año) en servicios públicos.
- La comunicación con bases de datos debe ser sobre TLS:
  `sslmode=require` en PostgreSQL, `require_secure_transport=ON` en MySQL.
- Las colas de mensajes (SQS, Pub/Sub, Service Bus) con cifrado de mensajes habilitado.

---

## Prohibición absoluta de credenciales hardcodeadas

Las credenciales en código fuente son una de las causas más comunes de brechas de seguridad.

- NUNCA hardcodear en código fuente: passwords, API keys, tokens de acceso,
  connection strings, certificados privados, IDs de cuenta, ARNs con cuenta específica.
- NUNCA hardcodear credenciales en Dockerfiles, docker-compose.yml, manifiestos
  de Kubernetes, archivos de Terraform, scripts de CI/CD.
- NUNCA commitear archivos `.env` con valores reales. Solo `.env.example` con
  nombres de variables y valores de placeholder.
- Usar el servicio de gestión de secretos correspondiente al cloud provider:
  - AWS: Secrets Manager o Parameter Store (SSM)
  - GCP: Secret Manager
  - Azure: Key Vault
  - Kubernetes: External Secrets Operator (integrando con el cloud secrets manager)
- Para variables de entorno en CI/CD, usar las variables de entorno cifradas
  del servicio de CI (GitHub Actions Secrets, GitLab CI Variables, etc.).
  NUNCA escribirlas en archivos de configuración del pipeline.
- Ejecutar `git-secrets` o `truffleHog` en el pipeline de CI para detectar
  credenciales accidentalmente commiteadas.
- Si se detecta una credencial comprometida en git:
  1. Revocarla/rotarla INMEDIATAMENTE
  2. Asumir que fue vista por actores maliciosos
  3. Limpiar el historial con `git filter-repo` o BFG Repo Cleaner
  4. No es suficiente con un commit que la borre — el historial es público

---

## Infraestructura como código (IaC) para todo recurso

Ningún recurso cloud se crea manualmente desde la consola en ambientes no locales.

- Todo recurso de producción y staging debe estar definido en código:
  Terraform, Pulumi, AWS CDK, AWS CloudFormation, Azure Bicep, o el equivalente.
- Los recursos creados manualmente no son reproducibles, no son auditables y no
  son recuperables en caso de desastre. Son deuda técnica crítica.
- El código de IaC vive en el repositorio del proyecto (o en un repositorio
  dedicado de infraestructura si el equipo es grande).
- Los cambios de infraestructura pasan por code review igual que el código de aplicación.
- Antes de aplicar cambios: `terraform plan` (o equivalente) debe revisarse
  y aprobarse. NUNCA aplicar IaC sin revisar el plan.
- Los cambios de infraestructura se despliegan a través del pipeline de CI/CD,
  no manualmente desde la terminal de un desarrollador.
- Los módulos de Terraform/Pulumi deben tener versiones pinneadas. No usar
  rangos abiertos en módulos de infraestructura.
- Estado de Terraform almacenado en backend remoto (S3+DynamoDB, GCS, Terraform Cloud)
  con locking habilitado. NUNCA usar estado local en equipos.

---

## Alta disponibilidad y multi-AZ para producción

Los servicios de producción deben tolerar la falla de una zona de disponibilidad.

- Las bases de datos de producción deben ser multi-AZ:
  RDS con Multi-AZ deployment, Cloud SQL con high availability, Azure SQL con Zone Redundancy.
- Los servidores de aplicación deben escalar horizontalmente en múltiples AZs.
  NUNCA desplegar en una sola instancia sin failover para servicios de producción.
- El load balancer debe distribuir tráfico entre múltiples AZs.
- Los buckets de object storage son multi-AZ por defecto en la mayoría de providers.
  Verificar que la clase de almacenamiento seleccionada sea multi-regional o multi-AZ.
- Para servicios con SLA de alta disponibilidad: considerar multi-región con
  routing DNS geográfico (Route 53 latency routing, Cloud DNS, Azure Traffic Manager).
- El objetivo de tiempo de recuperación (RTO) y el objetivo de punto de recuperación (RPO)
  deben estar definidos y documentados para cada servicio de producción.
- Las fallas de AZ deben probarse periódicamente (Game Days, Chaos Engineering).

---

## Backups automatizados con retención definida

Los datos deben poder recuperarse. Sin backups verificados, no hay recuperación.

- Todos los servicios con estado (bases de datos, filesystems, object storage crítico)
  deben tener backups automatizados configurados por IaC.
- La política de retención debe estar definida explícitamente:
  - Producción: mínimo 30 días de retención, recomendado 90 días
  - Staging: mínimo 7 días
  - Backups de largo plazo (compliance): definir según requisito regulatorio
- Los backups deben almacenarse en una cuenta o proyecto cloud diferente al de
  producción para protección contra eliminación accidental o ransomware.
- El cifrado de backups es obligatorio (misma regla que datos en reposo).
- La restauración de backups debe probarse mensualmente en staging.
  Un backup que no se ha restaurado exitosamente no existe.
- Configurar alertas cuando un backup falla. NUNCA descubrir la falla en el momento
  en que se necesita restaurar.
- Para bases de datos: point-in-time recovery (PITR) habilitado en producción.
  Permite restaurar a cualquier momento dentro de la ventana de retención.

---

## Monitoring, alertas y observabilidad obligatorios

Si no está monitorizado, no está en producción.

- Todo servicio de producción debe tener:
  - **Métricas de infraestructura**: CPU, memoria, disco, red (CloudWatch, Cloud Monitoring, Azure Monitor)
  - **Métricas de aplicación**: latencia p50/p95/p99, tasa de errores, throughput
  - **Logs centralizados**: CloudWatch Logs, Cloud Logging, Azure Log Analytics
  - **Trazas distribuidas**: X-Ray, Cloud Trace, Application Insights (si hay microservicios)
- Alertas obligatorias con acción definida (no alertas sin destinatario):
  - CPU > 80% por más de 5 minutos
  - Disco > 85% de uso
  - Tasa de errores HTTP 5xx > 1% del tráfico
  - Latencia p95 > umbral definido por SLA
  - Fallo de backup
  - Certificado TLS con vencimiento < 30 días
- Las alertas deben ir a un canal con responsable activo (PagerDuty, OpsGenie, Slack con on-call).
  NUNCA alertas que van a un buzón que nadie revisa.
- Implementar dashboards de salud accesibles al equipo completo.
- Los logs NO deben contener datos sensibles: passwords, tokens, PII, números de tarjeta.
  Configurar filtros de sanitización de logs.
- Retención de logs: mínimo 90 días en producción. Requisitos de compliance pueden
  requerir más (1-7 años según el sector).

---

## Tagging obligatorio de recursos

Los recursos sin tags son inauditables, sin dueño y sin costo asignable.

Los siguientes tags son OBLIGATORIOS en TODOS los recursos cloud:

```
proyecto:      nombre del proyecto o sistema (ej: "swl-core", "facturacion")
ambiente:      prod | staging | dev | test
equipo:        nombre del equipo responsable (ej: "backend", "infraestructura")
costo-center:  centro de costo para facturación interna (ej: "ing-2024", "cliente-abc")
```

Tags adicionales recomendados:

```
owner:         correo del responsable técnico
version:       versión del componente (si aplica)
auto-apagado:  "true" para recursos de dev/test que se apagan fuera de horario laboral
```

- Configurar políticas de gobernanza que rechacen la creación de recursos sin los
  tags obligatorios (AWS Service Control Policies, GCP Organization Policies).
- Los tags deben definirse en el IaC, no agregarse manualmente después.
- Usar los tags para:
  - Filtrar recursos por proyecto en las consultas de costo
  - Identificar recursos huérfanos (sin equipo asignado)
  - Implementar apagado automático de recursos de no-producción

---

## Segmentación de red (VPC, subnets, security groups)

La red debe estar diseñada con defensa en profundidad.

- Cada ambiente (prod, staging, dev) debe tener su propia VPC separada.
  NUNCA mezclar prod y dev en la misma VPC.
- Las bases de datos y servicios internos NUNCA deben tener IP pública.
  Deben vivir en subnets privadas sin ruta directa a internet.
- Los security groups deben seguir el principio de menor privilegio:
  - NUNCA `0.0.0.0/0` en reglas de ingreso de puertos de aplicación (80, 443 son excepciones para el LB)
  - NUNCA `0.0.0.0/0` en reglas de ingreso para SSH (22) o RDP (3389) en producción.
    Usar VPN, bastion host o AWS Systems Manager Session Manager.
  - Las reglas de egreso deben ser explícitas — no `0.0.0.0/0` sin justificación.
- El acceso SSH/RDP a instancias de producción debe ser a través de bastion host
  o VPN corporativa, nunca directamente desde internet.
- Los balanceadores de carga son los únicos recursos en subnets públicas.
  Las instancias de aplicación van en subnets privadas.
- VPC Flow Logs habilitados en producción para auditoría de tráfico de red.
- Network ACLs como capa adicional de defensa para subnets críticas.

---

## Checklist antes de desplegar un nuevo recurso en producción

- [ ] Definido en IaC — no creado manualmente en la consola
- [ ] Tag obligatorio de proyecto, ambiente, equipo y costo-center asignados
- [ ] Principio de menor privilegio aplicado a los roles IAM asociados
- [ ] Cifrado en reposo habilitado
- [ ] Comunicación sobre TLS configurada
- [ ] Multi-AZ configurado (si es un servicio con estado)
- [ ] Backups automatizados configurados con política de retención definida
- [ ] Monitoreo y alertas configuradas
- [ ] El recurso está en subnet privada (si no es un LB o CDN)
- [ ] No hay credenciales hardcodeadas en la configuración
- [ ] El código de IaC pasó code review
