Mínimo privilegio
Cada identidad con los permisos justos, sobre los recursos justos y durante el tiempo justo, para que un fallo no se convierta en un desastre.
Detrás de casi todos los incidentes graves en cloud hay dos fallos encadenados. El primero deja entrar al atacante: una dependencia vulnerable, una clave filtrada en un repositorio, un SSRF. El segundo convierte ese acceso en un desastre: la identidad comprometida tenía permisos de sobra. Del primer fallo nunca te librarás del todo. El segundo sí puedes controlarlo, y ese es el trabajo del mínimo privilegioMínimo privilegioCada identidad (persona, servicio o máquina) tiene solo los permisos imprescindibles para su tarea, durante el tiempo imprescindible..
Qué es#
Saltzer y Schroeder lo formularon en 1975: todo programa y todo usuario debería operar con el conjunto mínimo de privilegios necesario para completar su tarea. Cincuenta años después sigue siendo el mismo principio, aunque hoy las «identidades» ya no son solo personas:
- Personas: desarrolladores, operaciones, soporte, auditores.
- Servicios: la API de Citas, el worker de recordatorios, una función serverless.
- Máquinas y automatismos: el pipeline de CI/CD, scripts de backup, herramientas de terceros con acceso a tu cuenta.
Un permiso tiene tres dimensiones, y el mínimo privilegio las acota todas:
- Qué acciones (escribir un adjunto, no administrar todo el almacén).
- Sobre qué recursos (una carpeta concreta, no todo el almacenamiento).
- Cuándo y cómo: condiciones (desde qué red, con qué etiquetas, con MFA) y durante cuánto tiempo (credenciales temporales, acceso que caduca).
La métrica que guía todo es el radio de impactoRadio de impactoAlcance máximo del daño si un componente, credencial o identidad concreta se ve comprometida.: si mañana roban esta credencial, ¿qué puede hacer el atacante con ella?
Paso 1 de 6Credencial robada
Un atacante consigue las credenciales temporales del rol de la tarea de la API de Citas, por ejemplo explotando un fallo en la propia API.
El radio de impacto como pregunta de diseño#
Aplicado a Citas, el ejercicio es preguntar por cada identidad qué ocurre si cae:
| Identidad | Permisos razonables | Si se compromete… |
|---|---|---|
| Rol de tarea de la API | Leer y escribir en el almacén de adjuntos, leer su secreto de BD | Acceso a adjuntos y a la BD de la app, no al resto de la cuenta |
| Rol del worker | Consumir su cola de mensajes y enviar correo | Puede leer recordatorios pendientes y enviar emails |
| Rol de despliegue (CI/CD) | Actualizar el servicio y publicar imágenes de contenedor en su registro | Puede desplegar código, pero no tocar el control de acceso ni la BD |
| Persona de soporte | Solo lectura de logs de la app | Ve logs, no datos de pacientes |
Si en la última columna aparece «toda la cuenta», hay trabajo pendiente.
Acotar los permisos en la práctica#
Acotar acciones, recursos y condiciones#
La tentación habitual es dar permisos amplios «para que funcione» y prometer recortarlos después. El ejemplo siguiente usa políticas de AWS IAM —el control de acceso por identidad del proveedor de referencia de este sitio—, pero la forma de una política de mínimo privilegio es igual en cualquier nube: comparar lo que suele acabar en producción con lo que la API necesita de verdad.
Amplia «para que funcione»
Mínimo privilegio
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": ["s3:*", "rds:*", "secretsmanager:*"], "Resource": "*" } ]}{ "Version": "2012-10-17", "Statement": [ { "Sid": "Adjuntos", "Effect": "Allow", "Action": ["s3:PutObject", "s3:GetObject"], "Resource": "arn:aws:s3:::citas-adjuntos/uploads/*" }, { "Sid": "SecretoBD", "Effect": "Allow", "Action": "secretsmanager:GetSecretValue", "Resource": "arn:aws:secretsmanager:eu-west-1:111122223333:secret:citas/prod/db-??????" } ]}Fíjate en los detalles. La API no necesita administrar la base de datos (habla con ella por la red, no con su API de gestión) y solo lee un secreto concreto; el sufijo aleatorio del identificador se cubre con un comodín acotado en lugar de abrir el gestor de secretos entero.
Las condiciones afinan todavía más. Las más útiles, con su nombre en AWS como ejemplo:
- Origen de red: la petición tiene que llegar a través de una red o un endpoint concretos (
aws:SourceVpce). - Atributos (ABAC): comparar las etiquetas de la identidad con las del recurso; un rol con
equipo=citassolo toca recursos con la misma etiqueta (aws:PrincipalTagfrente aaws:ResourceTag). - Alcance de los listados: limitar qué prefijos del almacén se pueden listar (
s3:prefix). - MFA presente: exigir doble factor para las acciones sensibles de personas (
aws:MultiFactorAuthPresent).
Las condiciones habilitan además la denegación por defecto: la política del almacén de adjuntos puede denegar cualquier acceso que no venga de la red de producción, de modo que una credencial robada y usada desde fuera no sirva de nada.
Un rol por servicio#
Conviene separar dos roles que a menudo se confunden: el que la plataforma usa para arrancar tu servicio (descargar la imagen del contenedor, escribir logs) y el que usa tu código en ejecución. Y cada servicio de Citas tiene su propio rol: si la API y el worker compartieran uno, un fallo en cualquiera de los dos heredaría los permisos de ambos. El rol del worker, por ejemplo, solo necesita consumir su cola de mensajes y enviar correo; nada más.
Máquinas: CI/CD sin claves de larga duración#
El pipeline de Citas no guarda credenciales de larga duración en el repositorio. En su lugar usa identidad federada (OIDC): el proveedor de CI/CD presenta un token firmado y asume un rol de corta duración. La relación de confianza del rol restringe qué repositorio y qué entorno pueden asumirlo, no «la organización» entera.
Personas: acceso temporal y separación de funciones#
Para las personas, el mínimo privilegio también tiene una dimensión temporal:
- Solo lectura por defecto, con roles por función en un proveedor de identidad gestionado.
- Acceso elevado bajo demanda (just-in-time): se solicita, se aprueba, caduca solo y queda auditado.
- Separación de funciones: quien escribe el código no aprueba su propio despliegue a producción, y nadie puede a la vez desactivar los registros de auditoría y borrarlos.
- Break-glass: un acceso de emergencia muy vigilado, en lugar de administradores permanentes «por si acaso».
Barandillas: límites de permisos y políticas de organización#
Las políticas de identidad conceden permisos. Hay otros mecanismos que solo limitan, y el permiso efectivo es la intersección de todas las capas:
-
Política de identidad: lo que el rol dice que puede hacer.
-
Límite de permisos (permission boundary): el máximo que ese rol podrá tener jamás. Es útil cuando delegas la creación de roles a un equipo: pueden crear roles, pero nunca más potentes que el límite.
-
Política de organización (en AWS, las SCP de Organizations): el máximo para toda la cuenta. Nunca concede nada por sí sola.
-
Permiso efectivo: solo lo que permiten todas las capas a la vez (y siempre que no haya un
Denyexplícito en ninguna política aplicable).
Una política de organización típica en las cuentas de Citas protege la propia auditoría, incluso frente a un administrador comprometido: deniega en toda la cuenta las acciones que detendrían o borrarían los registros de auditoría y la detección de amenazas, sin excepción. Como esa capa no la puede sobrescribir ninguna política de identidad, nadie —ni un administrador— puede apagar los ojos del sistema.
Llegar al mínimo sin adivinar#
Nadie acierta a la primera con la lista exacta de acciones. El camino práctico es partir del uso real:
- Genera la política a partir de la actividad: muchas plataformas revisan los registros de auditoría de un rol y proponen una política con los servicios y acciones que de verdad usó (en AWS, IAM Access Analyzer).
- Valida la política antes de aplicarla, con un verificador que avise de permisos demasiado amplios o de errores.
- Detecta lo que sobra: los informes de unused access y last accessed señalan roles, claves y permisos sin uso desde hace meses.
- Repite periódicamente. Los permisos se acumulan con el tiempo (privilege creep): cambios de equipo, «solo para esta migración»…
Errores comunes#
Tu turno
Explica el mínimo privilegio con un ejemplo de tu trabajo actual
Elige una identidad real de tu trabajo: una persona, un servicio o un pipeline.
- ¿Qué permisos tiene hoy? ¿Cuáles usa de verdad? Mira los registros de auditoría, los informes de last accessed o los logs de tu proveedor de identidad.
- Si mañana robaran esa credencial, ¿qué podría hacer el atacante? Descríbelo en una frase: ese es su radio de impacto.
- ¿Qué cambio concreto lo reduciría: acotar acciones, acotar recursos, añadir condiciones, credenciales temporales o separar roles?
- ¿Qué barandilla (permission boundary, SCP o equivalente en tu plataforma) evitaría que vuelva a crecer?
| Campo | Tu respuesta |
|---|---|
| Identidad | |
| Permisos actuales | |
| Permisos realmente usados | |
| Radio de impacto hoy | |
| Cambio propuesto | |
| Radio de impacto después |
Reto
Un rol puede leer objetos del almacén de adjuntos, pero su límite de permisos solo permite escribirlos. ¿Puede leer?
▸Mostrar solución
No. El permiso efectivo es la intersección entre la política de identidad y el límite de permisos (y las políticas de organización). Leer está en la política, pero no en el límite, así que se deniega. Un límite nunca concede nada por sí mismo: solo recorta.
Reto
¿Por qué entregar un rol sin restringir el recurso (p. ej. iam:PassRole sobre «*») es tan peligroso si por sí solo no lee ni escribe datos?
▸Mostrar solución
Porque permite entregar cualquier rol a un servicio que ejecuta código: un contenedor, una
función serverless, una máquina virtual. Si además puedes crear ese recurso, tu código corre con
los permisos del rol que pasaste, que pueden ser de administrador. Restringe el permiso a recursos
concretos y, si puedes, a un servicio concreto (en AWS, iam:PassRole acotado por ARN y con la
condición iam:PassedToService).
En resumen#
- Mínimo privilegio = acotar qué, sobre qué, cuándo/cómo y durante cuánto tiempo, para personas, servicios y máquinas.
- La pregunta guía es el radio de impacto: si esta credencial cae, ¿qué cae con ella?
- En la práctica: recursos concretos en lugar de comodines, condiciones, un rol por servicio, identidad federada en lugar de claves y acceso elevado temporal.
- Los límites de permisos y las políticas de organización solo limitan, y el permiso efectivo es la intersección de todas las capas.
- No adivines: genera políticas a partir del uso real, elimina lo que no se usa y revisa periódicamente.
Referencias#
- Saltzer & Schroeder — The Protection of Information in Computer Systems (1975)
- AWS IAM — Security best practices
- IAM Access Analyzer — Policy generation · Unused access
- Permissions boundaries for IAM entities
- Service control policies (SCPs)
- Amazon ECS task IAM role
- GitHub Actions — Configuring OpenID Connect in AWS
- TEAM — Temporary elevated access management for IAM Identity Center