Ya sabes qué hay que proteger (lección 01-01) y de qué (lección 01-02). Queda la pregunta más importante: ¿con qué criterio se toman las decisiones? Nadie puede memorizar la lista infinita de configuraciones correctas, y ninguna lista sobreviviría al siguiente cambio tecnológico. Lo que sí sobrevive son los principios: un puñado de reglas de diseño, algunas formuladas hace más de cincuenta años, que siguen explicando por qué una arquitectura resiste y otra se desmorona. En esta lección vas a interiorizar esos principios y a verlos aplicados a decisiones concretas de Nimbus Reservas: los permisos de la cuenta con la que la API habla con PostgreSQL, las capas que rodean el bucket de adjuntos, quién puede desplegar a producción. Estos principios son la columna vertebral del resto del curso: cuando en el módulo 5 discutamos hardening o seguridad en la nube, estaremos aplicando lo de aquí.
Contenido
- Por qué principios y no recetas
- Mínimo privilegio y necesidad de conocer
- Defensa en profundidad
- Seguridad por defecto y seguridad desde el diseño
- Fallo seguro (fail-safe / fail-secure)
- Separación de funciones y rotación
- Mediación completa
- Economía del mecanismo y mínimo mecanismo común
- Aceptabilidad psicológica
- No confiar en la seguridad por oscuridad
- Confianza cero (Zero Trust) y el fin del perímetro
- Asume la brecha
- Tabla resumen y el compromiso seguridad-usabilidad-coste
- Por qué principios y no recetas
Marta, la CTO de Nimbus, recibe cada semana propuestas contradictorias: un proveedor le vende un cortafuegos de aplicación, un artículo dice que lo importante es el MFA, un cliente exige un cuestionario de 80 preguntas. Sin un criterio propio, la seguridad se convierte en una lista de compras.
Los principios que verás aquí proceden en su mayoría de un artículo de 1975 de Saltzer y Schroeder sobre protección de la información en sistemas informáticos, ampliado después por la práctica del sector. Han sobrevivido a los mainframes, al cliente-servidor, a la web y a la nube — y siguen explicando los incidentes de 2026. Esa longevidad es la razón de estudiarlos: una recomendación concreta caduca; un principio te permite generar la recomendación correcta para una tecnología que aún no existe.
Una advertencia antes de empezar: los principios entran en conflicto entre sí. La economía del mecanismo pide simplicidad; la defensa en profundidad añade capas. La seguridad por defecto pide restringir; la aceptabilidad psicológica pide no ahogar al usuario. Aplicarlos bien no es obedecerlos todos al máximo, sino saber cuál pesa más en cada decisión y poder explicar por qué.
- Mínimo privilegio y necesidad de conocer
2.1 Mínimo privilegio
Toda entidad —persona, proceso o servicio— debe tener exactamente los permisos que necesita para su función, ni uno más, y solo durante el tiempo que los necesita.
Es el principio más rentable de todos, porque limita el daño de cualquier fallo, venga de un ataque, de un error o de un bug. Si una credencial comprometida solo puede leer tres tablas, el atacante solo lee tres tablas.
Aplicado a Nimbus: la cuenta de base de datos de la API.
Iván arrancó el proyecto conectando la API con el superusuario postgres, «para no pelearse con permisos». Funciona perfectamente... hasta que una inyección SQL o un bug convierten esa comodidad en un desastre total: con el superusuario, un atacante puede leer cualquier tabla, borrarlas todas, crear usuarios nuevos y en algunos escenarios ejecutar comandos en el sistema.
Así se aplica mínimo privilegio en PostgreSQL:
-- === 1. Un rol sin capacidad de inicio de sesion que agrupa los permisos ===
CREATE ROLE nimbus_api_rol NOLOGIN;
-- === 2. Revocar lo que PostgreSQL concede por defecto ===
-- Por defecto, cualquier rol puede crear objetos en el esquema public.
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO nimbus_api_rol; -- ver el esquema, no crear en el
-- === 3. Conceder SOLO lo necesario, tabla a tabla y operacion a operacion ===
GRANT SELECT, INSERT, UPDATE ON reservas TO nimbus_api_rol;
GRANT SELECT, INSERT, UPDATE ON clientes_finales TO nimbus_api_rol;
GRANT SELECT ON servicios TO nimbus_api_rol; -- catalogo: solo lectura
GRANT SELECT, INSERT ON auditoria_accesos TO nimbus_api_rol; -- se anade, NO se modifica
GRANT USAGE ON ALL SEQUENCES IN SCHEMA public TO nimbus_api_rol; -- para los autoincrementales
-- === 4. Ni una sola tabla con DELETE ni DROP ===
-- Las bajas se hacen con borrado logico (columna borrado_en), no con DELETE.
-- === 5. Datos especialmente sensibles: nada por defecto ===
REVOKE ALL ON nominas FROM nimbus_api_rol; -- la API nunca toca RRHH
REVOKE ALL ON claves_pasarela FROM nimbus_api_rol;
-- === 6. El usuario real de la aplicacion hereda del rol ===
CREATE USER nimbus_api WITH PASSWORD :'clave_generada';
GRANT nimbus_api_rol TO nimbus_api;Explicación de las decisiones clave:
- Separar rol de usuario (pasos 1 y 6) permite rotar la contraseña o crear un segundo usuario (por ejemplo, para un worker asíncrono) sin volver a escribir todos los
GRANT. - El
REVOKEdel paso 2 es imprescindible. Mucha gente concede permisos y da por hecho que lo demás está cerrado; en PostgreSQL, el esquemapublices permisivo por defecto. Mínimo privilegio empieza por quitar, no por dar. auditoria_accesosconINSERTpero sinUPDATEniDELETE. Esto sostiene directamente la trazabilidad y el no repudio de 01-01: ni siquiera un atacante que se haga con la credencial de la API puede borrar su propio rastro desde ahí.- Sin
DELETEen ninguna tabla. UnDELETE FROM reservassinWHEREdeja de ser posible. El borrado lógico permite además recuperar sin restaurar copias. REVOKEexplícito sobrenominas. Aunque no se hubiera concedido, escribirlo documenta la intención y protege frente a unGRANT ... ON ALL TABLESfuturo hecho con prisa.
El mismo principio en la nube, con la política de la máquina que ejecuta la API:
# Politica de acceso al almacenamiento de objetos para el rol de la API
# Principio: solo SU prefijo, solo las acciones que usa, solo con cifrado
Version: "2012-10-17"
Statement:
- Sid: LeerYEscribirSoloAdjuntosDelTenant
Effect: Allow
Action:
- "s3:GetObject"
- "s3:PutObject"
Resource: "arn:aws:s3:::nimbus-adjuntos-prod/tenants/*" # NO el bucket entero
Condition:
StringEquals:
"s3:x-amz-server-side-encryption": "aws:kms" # obliga a cifrar al escribir
- Sid: ProhibidoBorrarYProhibidoTocarLasCopias
Effect: Deny # Deny gana siempre a Allow
Action:
- "s3:DeleteObject"
- "s3:PutBucketPolicy"
- "s3:PutBucketAcl"
Resource:
- "arn:aws:s3:::nimbus-adjuntos-prod/*"
- "arn:aws:s3:::nimbus-backups-prod/*"Puntos a destacar:
- El recurso es
/tenants/*, no*: la API no puede tocar los prefijos de configuración interna del bucket. - La condición de cifrado convierte «recordar cifrar» en «es imposible escribir sin cifrar».
- El bloque
Denyincluye las acciones que permitirían cambiar las reglas del juego (PutBucketPolicy,PutBucketAcl). Un atacante con esa credencial no puede autoconcederse más permisos. - Las copias de seguridad están explícitamente fuera del alcance de la API. Es la defensa estructural contra el ransomware: la carga de trabajo comprometida no alcanza la copia que te salva.
2.2 Necesidad de conocer (need to know)
Es el mismo principio aplicado a la información en vez de a las operaciones: no basta con tener el nivel de autorización adecuado; hay que necesitar ese dato para la tarea concreta.
Rubén, en soporte, tiene autorización general para consultar fichas de clientes finales. Pero no necesita ver todas las fichas de todos los clientes de Nimbus siempre. Necesita ver la ficha del cliente sobre el que hay un ticket abierto.
| Sin necesidad de conocer | Con necesidad de conocer |
|---|---|
Rubén tiene acceso permanente a toda la tabla clientes_finales |
El acceso se abre para el tenant del ticket asignado y se registra |
| La consultora externa tiene acceso a todos los entornos | Acceso solo al entorno del incidente, con ventana temporal limitada |
| El informe mensual de dirección incluye datos identificativos | El informe se genera agregado, sin identificadores personales |
En la práctica se implementa con acceso just-in-time (se concede al abrir el ticket y expira al cerrarlo), enmascaramiento de campos y agregación. Es también la base del principio de minimización de datos que exige la normativa de protección de datos (06-03).
- Defensa en profundidad
Ningún control es infalible. Coloca varios controles independientes en serie, de modo que el fallo de uno no sea el fallo del sistema.
La metáfora clásica es el castillo: foso, muralla, patio, torre del homenaje. La metáfora más honesta es el queso suizo: cada capa tiene agujeros, pero si las capas son independientes, es improbable que los agujeros se alineen.
Aplicado al activo más delicado de Nimbus —el bucket de adjuntos con partes médicos escaneados—:
flowchart TD
ATK[Atacante externo] --> L1
L1["CAPA 1 - PERIMETRO\nWAF y limitacion de peticiones\nSolo HTTPS, TLS 1.2+"] --> L2
L2["CAPA 2 - IDENTIDAD\nAutenticacion de la sesion\nMFA para cuentas internas"] --> L3
L3["CAPA 3 - AUTORIZACION\nPermiso + pertenencia al tenant\nverificada en cada peticion"] --> L4
L4["CAPA 4 - RED\nEl bucket no es publico\nAcceso solo desde la VPC"] --> L5
L5["CAPA 5 - PERMISOS DEL RECURSO\nPolitica de minimo privilegio\nsin DeleteObject"] --> L6
L6["CAPA 6 - DATO\nCifrado en reposo con KMS\nURLs firmadas y caducas"] --> L7
L7["CAPA 7 - DETECCION\nLog de accesos, alertas por\nvolumen anomalo de descargas"] --> L8
L8["CAPA 8 - RECUPERACION\nVersionado y copias inmutables\nen otra cuenta"]
Cómo se lee este diagrama. Un atacante que consiga saltarse una capa se encuentra con la siguiente. Y lo más importante: si consigue exfiltrar datos igualmente, las capas 7 y 8 siguen aportando valor — Nimbus se entera de qué se llevó y cuándo (trazabilidad), y no ha perdido la información (recuperación).
La condición que hace que funcione: independencia. Diez capas que dependen todas del mismo directorio de identidad no son diez capas; son una. Cuando diseñes tus capas, pregúntate: ¿qué fallo único derribaría varias a la vez? En Nimbus ese fallo único sería la cuenta de administrador del proveedor cloud: quien la tenga anula las capas 4, 5, 6 y 8 de golpe. De ahí que esa cuenta merezca protecciones desproporcionadas (MFA con llave física, uso excepcional, alertas en cada uso).
Errores frecuentes al aplicar defensa en profundidad:
- Apilar capas del mismo tipo. Tres antivirus distintos no son defensa en profundidad; son redundancia del mismo control.
- Usar la existencia de una capa para relajar otra. «Como tenemos WAF, no hace falta validar la entrada en el código.» El WAF es un filtro genérico y evadible; la validación en el código es la que conoce las reglas de negocio.
- Olvidar la capa de detección. Muchas arquitecturas tienen cinco capas de prevención y ninguna de detección. Si nadie mira, la brecha dura meses.
- Seguridad por defecto y seguridad desde el diseño
Son dos principios hermanos que suelen citarse juntos (y que la normativa europea de protección de datos recoge de forma explícita).
4.1 Seguridad por defecto (secure by default)
La configuración de fábrica debe ser la más restrictiva razonable. Si el usuario no toca nada, debe quedar protegido.
La configuración por defecto es la que acaba en producción en la mayoría de instalaciones. Cualquier valor por defecto inseguro se convierte, estadísticamente, en una vulnerabilidad masiva.
| Decisión en Nimbus | Por defecto inseguro | Por defecto seguro |
|---|---|---|
| Nuevo usuario en el panel de administración | Se crea con rol admin y se le quitan permisos después |
Se crea sin permisos; se conceden explícitamente |
| Nuevo bucket creado por Lucía | Hereda la configuración de la cuenta | Plantilla de infraestructura con bloqueo público y cifrado obligatorio |
| Nuevo endpoint que añade Iván | Público salvo que se añada el decorador de autenticación | Autenticación obligatoria salvo excepción explícita en una lista blanca |
| Nuevo cliente que se da de alta | Todos los módulos activados | Solo el módulo contratado |
| Registro de la API | Nivel DEBUG con cuerpos completos |
Nivel INFO sin datos personales |
El tercer caso merece código, porque es el que evita las fugas de datos más tontas. Comparemos:
# === PATRON INSEGURO POR DEFECTO ===
# El endpoint es publico salvo que alguien recuerde protegerlo.
@router.get("/api/v1/facturas")
async def listar_facturas(db=Depends(get_db)): # <-- olvidaron la dependencia de usuario
return await db.fetch_all("SELECT * FROM facturas")# === PATRON SEGURO POR DEFECTO ===
# La autenticacion se aplica a TODO el router; olvidarla es imposible.
router = APIRouter(dependencies=[Depends(exigir_usuario_autenticado)])
# Y las rutas realmente publicas se declaran una a una, de forma explicita y visible:
RUTAS_PUBLICAS = {"/api/v1/salud", "/api/v1/estado-servicio"}
@app.middleware("http")
async def exigir_autenticacion(peticion: Request, siguiente):
if peticion.url.path not in RUTAS_PUBLICAS:
if not await sesion_valida(peticion):
return JSONResponse({"detail": "No autenticado"}, status_code=401)
return await siguiente(peticion)La diferencia conceptual es enorme. En el primer patrón, la seguridad depende de que cada desarrollador recuerde cada vez. En el segundo, el fallo por omisión resulta en denegación, y abrir algo requiere un acto deliberado y revisable (añadir una ruta a RUTAS_PUBLICAS aparece en la revisión del código y llama la atención). Esto es también fallo seguro, que veremos en el apartado 5.
4.2 Seguridad desde el diseño (security by design)
La seguridad se incorpora al concebir el sistema, no como una revisión final.
El coste de corregir un fallo crece de forma brutal según en qué fase se detecta:
| Momento en que se detecta | Coste relativo de corregir | Ejemplo en Nimbus |
|---|---|---|
| Al diseñar | 1 | Decidir que cada tabla lleva tenant_id y que el filtro es obligatorio |
| Al programar | ~5 | Añadir la comprobación en un endpoint durante la revisión de código |
| En pruebas | ~15 | Detectar en QA que tres endpoints no filtran por tenant |
| En producción | ~50 | Parche urgente, despliegue fuera de ventana |
| Tras un incidente | ~200+ | Investigación forense, notificación, pérdida de clientes, reputación |
Un ejemplo concreto de decisión de diseño en Nimbus: en lugar de confiar en que cada consulta añada WHERE tenant_id = ..., se activa seguridad a nivel de fila en PostgreSQL, de modo que el aislamiento entre clientes lo garantiza la base de datos:
-- El aislamiento multi-cliente deja de depender de que nadie olvide un WHERE
ALTER TABLE reservas ENABLE ROW LEVEL SECURITY;
CREATE POLICY aislamiento_por_tenant ON reservas
USING (tenant_id = current_setting('app.tenant_actual')::int);
-- La API fija la variable de sesion al inicio de cada peticion, tras autenticar:
-- SET LOCAL app.tenant_actual = '42';
-- A partir de ahi, un "SELECT * FROM reservas" solo ve las filas del tenant 42.Por qué esto es diseño y no parche: el desarrollador ya no puede provocar una fuga entre clientes olvidando una cláusula. La propiedad de seguridad se ha movido a una capa donde el error es imposible, en vez de vigilarse en cada uno de los cientos de sitios donde podría cometerse. Nota práctica: SET LOCAL dentro de la transacción es clave si se usa un pool de conexiones, para que el valor no se filtre a la siguiente petición.
- Fallo seguro (fail-safe / fail-secure)
Cuando algo falla —y va a fallar— el sistema debe quedar en el estado más seguro posible. La decisión por defecto ante la duda es denegar.
La formulación clásica de Saltzer y Schroeder es fail-safe defaults: el acceso se basa en permiso explícito, no en ausencia de prohibición.
Hay que distinguir dos variantes que en español se confunden:
| Variante | Ante el fallo... | Prioriza | Ejemplo |
|---|---|---|---|
| Fail-secure | Se cierra / deniega | Confidencialidad e integridad | Si el servicio de autorización no responde, la API devuelve 403 |
| Fail-safe (seguridad física) | Se abre / libera | Vida humana, disponibilidad | Las puertas de emergencia se desbloquean si hay incendio |
En sistemas informáticos casi siempre queremos fail-secure; en sistemas con vidas en juego, fail-safe. Y a veces hay que elegir conscientemente.
El caso incómodo en Nimbus. El servicio que valida los permisos deja de responder. Dos opciones:
# === OPCION A: fail-open (PELIGROSA por defecto) ===
try:
permitido = await servicio_permisos.comprobar(usuario, accion)
except TimeoutError:
permitido = True # "para no romper el servicio"...
# ...un atacante que tumbe el servicio de permisos
# obtiene acceso total. El fallo es la llave.
# === OPCION B: fail-secure (CORRECTA en la mayoria de casos) ===
try:
permitido = await servicio_permisos.comprobar(usuario, accion)
except TimeoutError:
logger.error("event=permisos_no_disponibles actor=%s accion=%s", usuario.id, accion)
raise HTTPException(503, "Servicio temporalmente no disponible")
# Se deniega, se alerta y se degrada de forma visible.La opción A tiene una propiedad devastadora: convierte un ataque de denegación de servicio en una escalada de privilegios. El atacante ya no necesita robar credenciales; le basta con saturar el servicio de permisos.
Ahora bien, fail-secure aplicado sin criterio también hace daño. Si Nimbus decide que cualquier fallo interno impide reservar, un problema en el servicio de envío de correos dejaría a las clínicas sin agenda. La resolución correcta es degradación graduada:
| Componente que falla | Decisión | Justificación |
|---|---|---|
| Servicio de permisos | Denegar todo (fail-secure) | Sin autorización no se puede operar con seguridad |
| Servicio de email transaccional | Continuar, encolar y avisar | El correo es accesorio a la operación principal |
| Pasarela de pago | Denegar la operación de cobro | Nunca dar por bueno un pago no confirmado |
| Servicio de auditoría | Denegar en operaciones sensibles | Sin registro no hay trazabilidad ni no repudio |
Ese último caso es discutible y sirve para practicar el razonamiento: si no se puede registrar una exportación masiva de datos personales, ¿se permite hacerla a ciegas? En Nimbus, la respuesta acordada es no.
- Separación de funciones y rotación
6.1 Separación de funciones (segregation of duties)
Ninguna persona debe controlar en solitario todas las fases de un proceso crítico.
Es un principio nacido en auditoría contable y trasplantado a la informática con excelentes resultados. Protege a la vez contra el fraude deliberado y contra el error individual.
Aplicado a Nimbus:
| Proceso crítico | Sin separación (riesgo) | Con separación |
|---|---|---|
| Despliegue a producción | Iván programa, aprueba y despliega su propio código | Iván programa; otra persona aprueba la PR; el despliegue lo ejecuta el pipeline, no una persona |
| Pago a proveedores | Sara crea el proveedor y ordena el pago | Sara da de alta al proveedor; la orden de pago la autoriza dirección |
| Gestión de accesos | Lucía se autoconcede permisos de administrador cuando los necesita | La concesión requiere ticket aprobado por Marta y queda registrada |
| Revisión de los logs de auditoría | Lucía administra los sistemas y revisa sus propios registros | Los registros van a una cuenta separada a la que Lucía no tiene permiso de borrado |
Y así se materializa en la configuración del repositorio, que es donde vive de verdad la separación de funciones en una empresa de software:
# .github/branch-protection (representacion simplificada de la proteccion de rama)
branch: main
required_pull_request_reviews:
required_approving_review_count: 1
dismiss_stale_reviews: true # un push nuevo invalida la aprobacion anterior
require_code_owner_reviews: true # los ficheros sensibles exigen revisor concreto
required_status_checks:
strict: true
contexts:
- "tests"
- "analisis-estatico-seguridad"
- "escaneo-dependencias"
enforce_admins: true # la regla aplica TAMBIEN a los administradores
allow_force_pushes: false # no se puede reescribir la historia
allow_deletions: falseExplicación de las líneas que más importan:
enforce_admins: truees la que casi todo el mundo deja enfalse. Si Marta y Lucía pueden saltarse el proceso, el proceso no existe: basta comprometer una de esas dos cuentas.dismiss_stale_reviews: trueevita el truco de conseguir la aprobación con un cambio inocuo y añadir después el código real.allow_force_pushes: falseprotege la integridad histórica del repositorio: nadie puede borrar el rastro de un cambio.
Límite práctico en una PYME. En Nimbus hay una sola administradora de sistemas. La separación estricta es imposible: Lucía tiene que poder hacer su trabajo a las tres de la madrugada. Cuando la separación preventiva no es viable, se sustituye por controles compensatorios: registro inalterable de todas sus acciones en una cuenta a la que ella no puede escribir, alertas automáticas a Marta ante acciones críticas, y revisión periódica por un tercero. Es una respuesta honesta y perfectamente defendible ante un auditor.
6.2 Rotación
Complementa a la anterior: las personas cambian de puesto y las credenciales caducan.
- Rotación de personas: que otra persona pase por la función revela irregularidades y elimina la dependencia de un individuo (el llamado bus factor). Las vacaciones obligatorias son, históricamente, un control antifraude.
- Rotación de credenciales: claves de API, certificados y secretos con vida limitada. Una credencial que caduca cada 90 días acota la ventana de utilidad de una filtración. Mejor aún: credenciales efímeras emitidas por el proveedor de identidad, válidas durante minutos, que eliminan el secreto de larga vida por completo.
- Mediación completa
Cada acceso a cada recurso debe verificarse, cada vez. Sin excepciones, sin atajos, sin cachés que sobrevivan al cambio de permisos.
Este principio ataca un error muy concreto: comprobar los permisos una vez al inicio y confiar después.
Ejemplos de mediación incompleta en Nimbus:
- La SPA oculta el botón «Exportar clientes» si el usuario no tiene el permiso... pero el endpoint no lo comprueba. La interfaz no es un control de seguridad: cualquiera puede llamar a la API directamente.
- El token de sesión de Rubén dura 8 horas. Se le revocan los permisos a las 10:00, pero su token sigue siendo válido y con los permisos antiguos incrustados hasta las 18:00.
- Se comprueba la autorización al listar reservas, pero no al descargar el adjunto de una reserva concreta: la URL del fichero, si se conoce, funciona sin verificación.
Cómo se implementa correctamente el caso del adjunto:
@router.get("/api/v1/reservas/{reserva_id}/adjunto")
async def descargar_adjunto(reserva_id: int, usuario=Depends(get_usuario_actual), db=Depends(get_db)):
# MEDIACION COMPLETA: se vuelve a verificar aqui, aunque ya se verificara al listar
reserva = await db.fetch_one(
"SELECT adjunto_clave FROM reservas WHERE id=:id AND tenant_id=:t",
{"id": reserva_id, "t": usuario.tenant_id},
)
if reserva is None:
raise HTTPException(404, "No encontrada")
# Nunca se expone la URL permanente del objeto: se genera una firmada y caduca
url = generar_url_firmada(
clave=reserva["adjunto_clave"],
caducidad_segundos=120, # dos minutos: suficiente para descargar
solo_lectura=True,
)
logger.info("event=descarga_adjunto actor_id=%s recurso=reserva:%s", usuario.id, reserva_id)
return {"url": url}Las tres decisiones defendibles aquí: se reverifica la pertenencia aunque «ya se comprobó antes»; la URL firmada caduca en dos minutos, de forma que compartirla por error tiene una ventana mínima; y el acceso queda registrado, con lo que la mediación es además auditable.
La tensión de este principio es evidente: verificar siempre cuesta rendimiento. Se resuelve con cachés de muy corta duración y con invalidación explícita al cambiar permisos — nunca eliminando la verificación.
- Economía del mecanismo y mínimo mecanismo común
8.1 Economía del mecanismo (simplicidad)
El mecanismo de seguridad debe ser lo más pequeño y simple posible, porque solo lo simple se puede verificar.
Un sistema de permisos con 4 roles claros y auditables protege mejor en la práctica que uno con 60 permisos granulares que nadie entiende y que se conceden a bulto «porque no sabemos cuál falta». La complejidad no es un inconveniente estético: es el escondite de los fallos.
Señales de que Nimbus está violando este principio:
- Nadie sabe explicar en una frase por qué un usuario concreto puede hacer una acción concreta.
- Hay tres mecanismos distintos de autorización conviviendo (uno en el proxy, otro en el middleware, otro dentro de cada endpoint) y no está claro cuál manda.
- Para dar de alta a un empleado hay que tocar siete sitios y existe un documento de 20 páginas que casi nadie sigue.
Regla práctica: si no puedes dibujar tu modelo de autorización en una pizarra en cinco minutos, no puedes garantizar que sea correcto.
8.2 Mínimo mecanismo común
Minimiza los recursos y mecanismos compartidos entre usuarios o entre sistemas distintos, porque todo lo compartido es un canal potencial de fuga o de propagación.
Aplicado a Nimbus:
| Compartido (riesgo) | Separado (mejor) |
|---|---|
| Producción y preproducción en la misma cuenta cloud y la misma VPC | Cuentas separadas; un compromiso de preproducción no alcanza producción |
| Una única credencial usada por la API, los trabajos batch y los scripts de Lucía | Una credencial por identidad, con permisos distintos y rastreable |
| Datos reales copiados al entorno de pruebas | Datos anonimizados o sintéticos en pruebas |
| La misma wifi para empleados, invitados y las impresoras | Redes separadas; la de invitados sin acceso a la interna |
El caso de preproducción con datos reales es especialmente instructivo: los entornos de prueba tienen menos controles, menos vigilancia y más gente con acceso. Si contienen datos reales, has creado una copia de tu activo más sensible en tu entorno menos protegido — y, en términos de protección de datos, un tratamiento difícil de justificar.
- Aceptabilidad psicológica
Si un control es demasiado incómodo, la gente lo evita. Un control evitado no protege: además, oculta la exposición real.
Este principio, formulado ya en 1975, sigue siendo el más ignorado. La seguridad que no tiene en cuenta a las personas produce sistemáticamente lo contrario de lo que busca:
| Control mal diseñado | Comportamiento real que provoca | Alternativa aceptable |
|---|---|---|
| Cambio de contraseña cada 30 días con 5 reglas | Nimbus2026!, Nimbus2026!!, post-it bajo el teclado |
Contraseñas largas sin caducidad forzosa + MFA + gestor de contraseñas corporativo |
| Bloqueo de todos los servicios de transferencia de ficheros | Rubén usa su cuenta personal para mandar el CSV al cliente | Servicio corporativo cómodo, con caducidad y registro |
| Solicitud de acceso con 3 aprobaciones y 5 días de espera | Se comparten credenciales entre compañeros «mientras tanto» | Acceso just-in-time autoservicio, con aprobación de una persona y registro |
| MFA en cada acción, cada 10 minutos | Se busca cómo desactivarlo; se aprueban notificaciones sin leerlas | MFA al iniciar sesión y en acciones sensibles; sesiones de duración razonable |
La regla operativa: haz que el camino seguro sea el camino fácil. Si el gestor de contraseñas corporativo es más cómodo que el bloc de notas, se usará. Si el servicio de transferencia interno es más rápido que WeTransfer, se usará. Diseñar así requiere más trabajo por adelantado, pero es la única forma de que un control sobreviva al segundo mes.
Aviso de diagnóstico: si en Nimbus descubres que la gente se salta un control, la primera hipótesis no debe ser «son irresponsables», sino «el control está mal diseñado». Casi siempre lo es. Este enfoque conecta con la lección de formación y concienciación (06-05).
- No confiar en la seguridad por oscuridad
La seguridad de un sistema no debe depender de que su diseño sea secreto. Debe depender de que sus claves lo sean.
Es el principio de Kerckhoffs, formulado en el siglo XIX para la criptografía militar y válido para cualquier sistema: el diseño puede caer en manos del enemigo sin que ello comprometa la seguridad.
Qué es oscuridad ilegítima (no protege):
- Poner el panel de administración en
/panel-secreto-nimbus-2024y no exigir autenticación fuerte. Se encuentra con un escaneo automatizado de rutas. - Cifrar con un algoritmo propio «que nadie conoce». Los algoritmos caseros se rompen casi siempre; los estándares son públicos precisamente porque han resistido décadas de análisis.
- Confiar en que un identificador de reserva sea largo y difícil de adivinar en lugar de comprobar la autorización.
- Ocultar la versión del servidor en las cabeceras como única medida frente a una vulnerabilidad conocida sin parchear.
Qué sí es legítimo (y no es lo mismo):
- No publicar innecesariamente detalles internos. Reducir la información que regalas es útil como capa adicional; simplemente no puede ser tu única capa.
- Los secretos que están diseñados para ser secretos: claves criptográficas, contraseñas, tokens. Ahí el secreto no es oscuridad: es el mecanismo.
- La diferencia clave: un secreto legítimo se puede rotar si se filtra. Si tu seguridad depende de que nadie sepa la ruta de tu panel, cuando se filtre tendrás que rediseñar; si depende de una clave, la cambias.
Corolario práctico para Nimbus: cuando Marta evalúe una herramienta de seguridad, debe desconfiar del proveedor que se niegue a explicar cómo funciona. «Es propietario, no podemos dar detalles» no es una respuesta aceptable sobre un mecanismo criptográfico.
- Confianza cero (Zero Trust) y el fin del perímetro
11.1 Por qué murió el perímetro
El modelo clásico dividía el mundo en dos: fuera (peligroso) y dentro (de confianza). Un cortafuegos en la frontera y listo. En Nimbus, ese modelo es sencillamente inaplicable:
- La mitad de la plantilla trabaja desde casa. ¿Dónde está el «dentro»?
- Los servidores están en un proveedor cloud, no en la oficina.
- Una consultora externa accede en remoto con privilegios elevados.
- La app móvil de los usuarios finales se conecta desde cualquier red del mundo.
- Los datos viven en un bucket S3 y en servicios SaaS de terceros.
Además, el modelo de perímetro tiene un fallo estructural: una vez dentro, no hay nada más. Un atacante que compromete un portátil se mueve lateralmente sin resistencia — que es exactamente lo que hace el ransomware moderno.
11.2 Los principios de Zero Trust
Nunca confíes, verifica siempre. La ubicación en la red no otorga privilegios.
flowchart TB
subgraph PER["MODELO DE PERIMETRO (obsoleto)"]
direction LR
FW[Cortafuegos] --> INT["Red interna\nTODO confia en TODO"]
end
subgraph ZT["MODELO ZERO TRUST"]
direction LR
U[Usuario o servicio] --> V{"Verificacion en cada acceso\nidentidad + dispositivo +\ncontexto + permiso minimo"}
V -->|permitido, sesion corta| REC[Recurso concreto]
V -->|denegado| X[Bloqueo y registro]
end
Zero Trust se apoya en tres ideas que ya conoces, combinadas:
- Verificación explícita en cada acceso (mediación completa) usando toda la señal disponible: quién eres, desde qué dispositivo, en qué estado está ese dispositivo, a qué hora, desde dónde.
- Mínimo privilegio con acceso just-in-time y sesiones cortas.
- Asumir la brecha: microsegmentación, cifrado extremo a extremo y análisis continuo, de forma que un compromiso quede acotado.
Qué significa concretamente en Nimbus:
| Antes (perímetro) | Con Zero Trust |
|---|---|
| «Si estás en la VPN, puedes llegar a la base de datos» | El acceso a la BD requiere identidad verificada, dispositivo gestionado y una ventana temporal aprobada |
| La API confía en las peticiones que vienen de la red interna | Los servicios se autentican entre sí con mTLS o tokens de servicio |
| El portátil de la consultora entra en la red interna completa | Acceso solo al sistema concreto del incidente, con grabación de sesión |
| Los contenedores de la misma VPC se hablan libremente | Políticas de red que solo permiten los flujos declarados |
Aviso importante: Zero Trust no es un producto que se compra. Es una arquitectura y un recorrido de varios años. Para Nimbus, empezar es perfectamente realista sin gran inversión: eliminar la confianza implícita por red en el acceso a la base de datos, exigir MFA a todas las cuentas administrativas y acotar el acceso de la consultora ya son tres pasos de Zero Trust.
- Asume la brecha
Diseña partiendo de que el atacante ya está dentro. La pregunta no es «¿cómo lo impido?», sino «¿cuánto daño puede hacer y en cuánto tiempo me entero?».
Es un cambio de mentalidad más que un control. Cambia las preguntas que se hacen en las reuniones de arquitectura:
| Pregunta de mentalidad preventiva | Pregunta de «asume la brecha» |
|---|---|
| ¿Cómo evito que entren? | Si entran por el portátil de Rubén, ¿a qué llegan desde ahí? |
| ¿Está protegida la base de datos? | Si roban la copia de la base de datos, ¿los datos están cifrados y con qué clave? |
| ¿Tenemos copias de seguridad? | ¿Puede el atacante que controla la infraestructura borrar esas copias? |
| ¿Tenemos logs? | ¿En cuánto tiempo detectaríamos una exfiltración lenta y sostenida? |
| ¿Es seguro nuestro CI/CD? | Si comprometen un token de GitHub Actions, ¿qué puede desplegar y quién lo aprueba? |
Las tres consecuencias de diseño más importantes:
- Segmentación: que el compromiso de un componente no dé acceso al siguiente.
- Copias fuera de alcance: copias inmutables o en otra cuenta, de modo que las credenciales de producción no puedan destruirlas. Es la diferencia entre pagar un rescate y no pagarlo.
- Detección y respuesta: métrica del tiempo de detección. Una organización que detecta en horas sufre un incidente; una que detecta en meses sufre una catástrofe.
Este enfoque se desarrolla operativamente en el plan de respuesta a incidentes (04-05) y en las técnicas de monitorización (05-02).
- Tabla resumen y el compromiso seguridad-usabilidad-coste
13.1 Los principios de un vistazo
| Principio | Qué evita | Decisión concreta en Nimbus |
|---|---|---|
| Mínimo privilegio | Que un fallo se convierta en compromiso total | La cuenta nimbus_api no tiene DELETE ni acceso a nominas |
| Necesidad de conocer | Exposición innecesaria de datos | Rubén ve la ficha del ticket abierto, no toda la tabla |
| Defensa en profundidad | Que un único fallo derribe el sistema | 8 capas alrededor del bucket de adjuntos |
| Seguridad por defecto | Configuraciones inseguras que llegan a producción | Router con autenticación obligatoria; rutas públicas en lista blanca |
| Seguridad desde el diseño | Correcciones caras y tardías | Aislamiento multi-cliente en la base de datos (RLS), no en cada consulta |
| Fallo seguro | Que un fallo abra las puertas | Si el servicio de permisos no responde, se deniega y se alerta |
| Separación de funciones | Fraude y errores sin control | enforce_admins: true; nadie aprueba su propio despliegue |
| Rotación | Credenciales eternas y dependencias personales | Claves con caducidad; credenciales efímeras |
| Mediación completa | Permisos comprobados «una vez y ya» | Se reverifica la propiedad al descargar cada adjunto |
| Economía del mecanismo | Complejidad que esconde fallos | Cuatro roles claros en lugar de sesenta permisos sueltos |
| Mínimo mecanismo común | Propagación entre entornos | Cuentas cloud separadas; sin datos reales en pruebas |
| Aceptabilidad psicológica | Controles que se evitan | Gestor de contraseñas cómodo en vez de caducidad cada 30 días |
| Nada de oscuridad | Seguridad que se evapora al publicarse el diseño | Nada de criptografía propia; nada de rutas «secretas» como única defensa |
| Confianza cero | Movimiento lateral tras el primer compromiso | Estar en la VPN no da acceso a la base de datos |
| Asume la brecha | Ceguera ante el incidente en curso | Copias inmutables en otra cuenta; medición del tiempo de detección |
13.2 Cómo se resuelve la tensión
Todos estos principios cuestan dinero, tiempo o comodidad. La forma profesional de resolver la tensión tiene cuatro pasos:
- Clasifica el activo. No todo merece lo mismo. Las notas médicas del bucket de adjuntos y el catálogo público de servicios no requieren las mismas capas. Aplicar el máximo a todo agota el presupuesto y la paciencia del equipo, y acaba en un nivel mediocre uniforme.
- Aplica el principio proporcionalmente. Mínimo privilegio riguroso en producción; algo más flexible en un entorno de desarrollo sin datos reales (y esa condición es la que lo hace aceptable).
- Mide la fricción, no la supongas. Si el MFA añade 6 segundos dos veces al día, es asumible; si obliga a Rubén a autenticarse 40 veces en una mañana, se convertirá en un problema y encontrará la forma de saltárselo.
- Documenta lo que aceptas y quién lo acepta. Si Nimbus decide no separar funciones en administración de sistemas porque solo hay una persona, eso se escribe, se explica el control compensatorio y lo firma la dirección. Un riesgo aceptado y documentado es gestión; un riesgo aceptado en silencio es negligencia.
Nota sobre implicaciones legales: varios de estos principios —seguridad desde el diseño y por defecto, minimización de datos— aparecen como obligaciones expresas en la normativa europea de protección de datos. Su aplicación concreta a tu caso debe validarse con el responsable de cumplimiento o con un profesional del ámbito jurídico; lo que aquí se ofrece es formación técnica, no asesoramiento legal.
Errores Comunes y Consejos
Errores comunes:
- Conceder permisos «temporalmente» sin fecha de fin. El acceso temporal más duradero del mundo es el que se concede un viernes para salir del paso. Toda concesión excepcional debe llevar caducidad automática.
- Confundir defensa en profundidad con redundancia. Capas del mismo tipo comparten los mismos puntos ciegos.
- Aplicar fail-open «para que no se rompa nada». Convierte una caída en una escalada de privilegios. Si has de abrir ante un fallo, que sea una decisión consciente y documentada, no el
exceptque quedó ahí. - Creer que la interfaz protege. Ocultar un botón no protege el endpoint. La seguridad se aplica en el servidor, siempre.
- Tomarse la simplicidad como excusa para no hacer nada. «Economía del mecanismo» no significa «no pongamos autorización»; significa que la autorización que pongas debe ser comprensible.
- Implantar Zero Trust como compra de producto. Ningún proveedor te vende Zero Trust; te vende una pieza. La arquitectura la diseñas tú.
- Olvidar la aceptabilidad psicológica en las políticas. Una política que el equipo no puede cumplir genera incumplimiento generalizado, y con él la pérdida de credibilidad de todas las demás.
Consejos:
- Ante cualquier decisión, recorre mentalmente tres principios: ¿es el mínimo privilegio posible? ¿qué pasa si esto falla? ¿hay más de una capa? Cubre la mayoría de los casos.
- Escribe los permisos como código (SQL, políticas, ficheros de configuración) y guárdalos en el repositorio. Lo que se revisa en una PR se discute; lo que se hace a mano en una consola, no.
- Empieza por revocar, no por conceder. La postura por defecto debe ser el cierre.
- Cuando debas violar un principio por razones prácticas, escríbelo con su control compensatorio. Un principio incumplido y documentado es gestionable; uno incumplido en silencio, no.
Ejercicios
Ejercicio 1 — Diagnosticar qué principios se violan
Marta encuentra esta situación al revisar la infraestructura de Nimbus. Identifica todos los principios que se están violando en cada punto y propón la corrección:
- La API se conecta a PostgreSQL con el usuario
postgres(superusuario), y la misma credencial la usan los trabajos nocturnos y los scripts manuales de Lucía. - El panel de administración interno está en
https://admin.nimbusreservas.example, sin restricción de red ni MFA, pero «nadie conoce esa URL». - El middleware de autorización tiene un bloque
except Exception: return Truepara «evitar caídas». - La política de contraseñas obliga a cambiarla cada 30 días con mayúsculas, minúsculas, números y símbolos; el 60 % del equipo usa variantes numeradas de la misma contraseña.
Ejercicio 2 — Escribir permisos de mínimo privilegio
Nimbus va a añadir un servicio nuevo, nimbus-informes, que genera cada noche un informe agregado de ocupación por cliente. El servicio:
- Lee de las tablas
reservasyservicios. - Escribe el resultado en la tabla
informes_ocupacion. - Sube un PDF al prefijo
informes/del bucketnimbus-adjuntos-prod. - No debe acceder a
clientes_finales, ni anominas, ni borrar nada.
Escribe (a) los GRANT/REVOKE de PostgreSQL y (b) el esqueleto de la política de acceso al bucket. Justifica las decisiones que no sean obvias.
Ejercicio 3 — Diseñar capas de defensa en profundidad
Nimbus va a permitir que sus clientes descarguen un fichero CSV con todas sus reservas del último año. Es una funcionalidad de exportación masiva de datos personales. Diseña al menos cinco capas independientes de defensa alrededor de esta funcionalidad, indicando para cada capa qué principio la sustenta y qué ataque o error concreto mitiga.
Soluciones
Solución 1
1. Superusuario compartido:
- Viola mínimo privilegio: la API puede borrar tablas, crear usuarios y leer todo, cuando solo necesita operar sobre cuatro tablas.
- Viola mínimo mecanismo común: una sola credencial para tres identidades distintas (API, batch, humana).
- Viola separación de funciones: si Lucía usa la misma credencial que la aplicación, sus acciones son indistinguibles de las de la API en los registros — se pierden trazabilidad y no repudio.
- Corrección: un rol por identidad (
nimbus_api_rol,nimbus_batch_rol, cuenta nominal para Lucía), conGRANTacotados como en el apartado 2.1; ningún servicio con superusuario; acceso administrativo bajo petición con caducidad.
2. Panel sin protección real:
- Viola no confiar en la oscuridad: la URL se descubre por certificados públicos, DNS y escaneo. Es lo primero que hace un bot.
- Viola defensa en profundidad: hay una única barrera, y es ficticia.
- Viola seguridad por defecto: un panel administrativo debería nacer restringido.
- Corrección: MFA obligatorio, restricción a rangos de red o acceso solo mediante identidad verificada, limitación de intentos, registro de todos los accesos y alerta ante accesos fuera de horario.
3. except Exception: return True:
- Viola fallo seguro de forma grave: convierte cualquier error —incluido uno provocable por un atacante— en autorización concedida.
- Viola mediación completa: la verificación deja de existir cuando más falta hace.
- Corrección: capturar excepciones concretas, denegar el acceso, registrar el error con nivel
ERRORy alertar. Si por una razón de negocio hubiera que degradar en abierto, debe limitarse a operaciones de solo lectura no sensibles y estar documentado y aprobado por escrito.
4. Política de contraseñas:
- Viola aceptabilidad psicológica: la carga es tal que el equipo genera patrones predecibles, más débiles que una contraseña larga estable.
- Viola indirectamente economía del mecanismo: la complejidad de la regla no aporta seguridad proporcional.
- Corrección: contraseñas largas (frases de paso), sin caducidad forzosa salvo indicio de compromiso, comprobación contra listas de contraseñas filtradas, gestor de contraseñas corporativo y MFA. La caducidad periódica obligatoria está desaconsejada por las guías actuales precisamente por este efecto.
Solución 2
(a) PostgreSQL:
CREATE ROLE nimbus_informes_rol NOLOGIN;
-- Ver el esquema, sin poder crear objetos en el
REVOKE ALL ON SCHEMA public FROM PUBLIC;
GRANT USAGE ON SCHEMA public TO nimbus_informes_rol;
-- Lectura estricta de lo que necesita agregar
GRANT SELECT ON reservas TO nimbus_informes_rol;
GRANT SELECT ON servicios TO nimbus_informes_rol;
-- Escritura solo en su tabla de resultados; sin UPDATE ni DELETE:
-- cada ejecucion anade un informe nuevo, no reescribe los anteriores (integridad historica)
GRANT SELECT, INSERT ON informes_ocupacion TO nimbus_informes_rol;
GRANT USAGE ON SEQUENCE informes_ocupacion_id_seq TO nimbus_informes_rol;
-- Prohibiciones explicitas, aunque no se hubieran concedido: documentan la intencion
REVOKE ALL ON clientes_finales FROM nimbus_informes_rol;
REVOKE ALL ON nominas FROM nimbus_informes_rol;
REVOKE ALL ON auditoria_accesos FROM nimbus_informes_rol;
CREATE USER nimbus_informes WITH PASSWORD :'clave_generada';
GRANT nimbus_informes_rol TO nimbus_informes;Decisiones no obvias, justificadas:
- Sin
UPDATEeninformes_ocupacion: un informe generado no se modifica. Si hay que corregirlo, se genera otro. Esto preserva el histórico y facilita detectar manipulaciones. REVOKEexplícitos: protegen frente a un futuroGRANT ... ON ALL TABLES IN SCHEMA publichecho con prisa, que de otro modo daría acceso a datos personales a un servicio que solo debe agregar.- Mejor aún, seguridad desde el diseño: si el informe es agregado, lo ideal es que ni siquiera lea
reservasdirectamente, sino una vista que exponga solo las columnas necesarias (tenant_id,fecha_hora,servicio_id) sin datos identificativos. Menos privilegio y menos superficie de fuga.
(b) Política del bucket:
Version: "2012-10-17"
Statement:
- Sid: SubirSoloInformes
Effect: Allow
Action: "s3:PutObject"
Resource: "arn:aws:s3:::nimbus-adjuntos-prod/informes/*" # solo su prefijo
Condition:
StringEquals:
"s3:x-amz-server-side-encryption": "aws:kms"
- Sid: NiLeerAdjuntosNiBorrarNada
Effect: Deny
Action:
- "s3:GetObject" # no necesita leer: solo escribe
- "s3:DeleteObject"
- "s3:PutBucketPolicy"
- "s3:PutBucketAcl"
Resource: "arn:aws:s3:::nimbus-adjuntos-prod/*"Nota: el Deny sobre s3:GetObject es deliberado y quizá el punto más interesante del ejercicio. Un servicio que solo sube ficheros no necesita leer el resto del bucket, donde viven los partes médicos escaneados de los pacientes. Si el servicio se ve comprometido, el atacante no obtiene esa lectura.
Solución 3 — Capas para la exportación masiva de CSV:
| # | Capa | Principio | Qué mitiga |
|---|---|---|---|
| 1 | Permiso específico datos:exportar, no incluido en el rol básico; solo el administrador del cliente lo tiene |
Mínimo privilegio | Que cualquier recepcionista descargue toda la base de datos del negocio |
| 2 | Reverificación de identidad (MFA) en el momento de exportar, aunque la sesión ya esté iniciada | Mediación completa, necesidad de conocer | Uso de una sesión robada o de un equipo desatendido |
| 3 | Filtro obligatorio por tenant_id aplicado en la base de datos mediante RLS, no en la consulta |
Seguridad desde el diseño | Que un olvido en el código exporte datos de otros clientes |
| 4 | Límite de rango (máximo 12 meses), de tamaño y de frecuencia (una exportación cada 24 h por cliente) | Fallo seguro, disponibilidad | Exfiltración masiva repetida; agotamiento de recursos |
| 5 | Generación asíncrona y entrega por URL firmada con caducidad de 15 minutos, de un solo uso, nunca adjunta por correo | Mínimo privilegio, defensa en profundidad | Reenvío accidental del enlace; enlaces permanentes indexables |
| 6 | Registro de auditoría con actor, tenant, filas exportadas, IP y hora, en almacenamiento sin permiso de borrado | Trazabilidad, no repudio, separación de funciones | Negación posterior; incapacidad de investigar un incidente |
| 7 | Alerta automática a Marta y correo al administrador del cliente ante cada exportación | Asume la brecha | Exfiltración silenciosa mediante una cuenta comprometida |
| 8 | Columnas mínimas en el CSV (sin notas internas ni identificadores de pago) y cifrado del fichero en reposo | Necesidad de conocer, mínimo privilegio | Que la fuga de un CSV exponga más de lo imprescindible |
Las capas son independientes: fallar el permiso (1) no anula el aislamiento en base de datos (3), y aunque el fichero se filtre, el contenido está minimizado (8) y el hecho queda registrado y alertado (6, 7). Nota adicional: una exportación de datos personales tiene implicaciones de cumplimiento —base legal, información al interesado, registro de la actividad— que deben validarse con el responsable de protección de datos.
Conclusión
Has recorrido los quince principios que sostienen todas las decisiones técnicas del resto del curso. Mínimo privilegio y necesidad de conocer limitan el daño de cualquier fallo, y los has visto materializados en los GRANT de la cuenta nimbus_api —sin DELETE, sin acceso a nóminas, con INSERT pero no UPDATE sobre la auditoría— y en una política de bucket que impide a la propia API borrar objetos o reescribir las reglas. Defensa en profundidad apila capas independientes alrededor de los adjuntos médicos, incluyendo las de detección y recuperación que tantas arquitecturas olvidan. Seguridad por defecto y desde el diseño desplazan la protección de «que nadie se olvide» a «que sea imposible olvidarse», como hace la seguridad a nivel de fila en PostgreSQL. Fallo seguro te ha enseñado que un except mal puesto convierte una caída en una escalada de privilegios.
Has visto también los principios que se olvidan más a menudo y que más caros salen: la separación de funciones con enforce_admins: true y sus controles compensatorios cuando en una PYME solo hay una administradora; la mediación completa que vuelve a verificar en cada descarga; la economía del mecanismo, que te obliga a poder dibujar tu modelo de autorización en una pizarra; la aceptabilidad psicológica, que explica por qué la política de contraseñas más estricta produce las contraseñas más débiles; y el rechazo a la seguridad por oscuridad, con la distinción entre un secreto rotable y un diseño oculto. Y has cerrado con las dos ideas que definen la seguridad moderna: confianza cero —la ubicación en la red no otorga privilegios— y asume la brecha, que cambia la pregunta de «¿cómo lo impido?» a «¿cuánto daño puede hacer y en cuánto tiempo me entero?».
Ahora sabes qué proteger, de qué y con qué criterio. Falta lo más concreto: saber exactamente qué tiene Nimbus. En la siguiente lección, Activos, Superficie de Ataque y Actores de Amenaza (01-04), construiremos el inventario de activos de la empresa con propietario, criticidad y clasificación de la información; mediremos su superficie de ataque en todas sus dimensiones; conoceremos a los actores que podrían atacarla y por qué a una PYME le afecta sobre todo el ataque automatizado; y darás tus primeros pasos con STRIDE sobre un diagrama de flujo de datos real de Nimbus.
Curso de Fundamentos de Seguridad Informática
Módulo 1: Introducción a la Seguridad Informática
- Conceptos Básicos de Seguridad Informática
- Tipos de Amenazas y Vulnerabilidades
- Principios de la Seguridad Informática
- Activos, Superficie de Ataque y Actores de Amenaza
Módulo 2: Ciberseguridad
- Definición y Alcance de la Ciberseguridad
- Tipos de Ataques Cibernéticos
- Ingeniería Social y Phishing
- Medidas de Protección en Ciberseguridad
- Identidad, Autenticación y Control de Acceso
- Casos de Estudio de Incidentes de Ciberseguridad
Módulo 3: Criptografía
- Introducción a la Criptografía
- Criptografía Simétrica
- Criptografía Asimétrica
- Funciones Hash, HMAC y Almacenamiento de Contraseñas
- Protocolos Criptográficos
- Gestión de Claves, Certificados y PKI
- Aplicaciones de la Criptografía
Módulo 4: Gestión de Riesgos y Medidas de Protección
- Evaluación de Riesgos
- Políticas de Seguridad
- Controles de Seguridad
- Riesgo de Terceros y Cadena de Suministro
- Plan de Respuesta a Incidentes
- Recuperación ante Desastres y Continuidad de Negocio
Módulo 5: Herramientas y Técnicas de Seguridad
- Herramientas de Análisis de Vulnerabilidades
- Técnicas de Monitoreo y Detección
- Pruebas de Penetración
- Seguridad en Redes
- Seguridad en Aplicaciones
- Hardening de Sistemas y Seguridad del Endpoint
- Seguridad en la Nube y en Contenedores
Módulo 6: Buenas Prácticas y Normativas
- Buenas Prácticas en Seguridad Informática
- Normativas y Estándares de Seguridad
- Protección de Datos Personales y RGPD en la Práctica
- Cumplimiento y Auditoría
- Formación y Concienciación
- Ética, Aspectos Legales y Divulgación Responsable
