AWS KMS: ¿Clave Administrada por AWS o CMK para Cifrar tu Bucket S3?
Cuando configuras cifrado en un bucket S3 por primera vez, la pantalla de la consola te presenta opciones que parecen equivalentes pero tienen implicaciones operativas y de costos muy distintas. Elegir entre una clave administrada por AWS y una clave administrada por el cliente (CMK) no es solo una decisión de seguridad — define quién controla el acceso, quién paga por cada operación criptográfica, y qué tan rápido puedes revocar acceso en una emergencia.
TL;DR: AWS Managed Key vs. CMK para S3
| Dimensión | AWS Managed Key (aws/s3) | Customer Managed Key (CMK) |
|---|---|---|
| Creación y rotación | Automática, gestionada por AWS | Manual o programada, controlada por ti |
| Política de clave | No editable | Totalmente configurable |
| Costo por API call | Sin cargo directo para S3 SSE-KMS | Cargo por cada llamada a la API de KMS |
| Auditoría granular | CloudTrail básico | CloudTrail con contexto de cifrado completo |
| Revocación de acceso | Solo vía IAM/bucket policy | Deshabilitar clave o modificar key policy |
| Cross-account access | No soportado directamente | Soportado vía key policy |
| Caso de uso típico | Cumplimiento básico, datos internos | Datos regulados, multi-cuenta, auditoría estricta |
Cómo Funciona el Cifrado en S3 con AWS KMS
S3 con SSE-KMS no cifra los objetos directamente con la clave KMS. Usa un modelo de cifrado en dos capas: KMS genera una data key única por objeto, cifra el objeto con esa data key (usando AES-256), y luego cifra la data key con tu clave KMS. Solo la data key cifrada se almacena junto al objeto. La clave KMS nunca sale del servicio KMS.
Esto significa que cada operación PutObject y GetObject sobre un objeto cifrado con SSE-KMS genera una llamada a la API de KMS (GenerateDataKey al escribir, Decrypt al leer). Ese detalle es el origen del costo variable que muchos equipos no anticipan.
- PutObject: S3 llama a KMS
GenerateDataKeypara obtener una data key en texto plano y su versión cifrada. - Cifrado del objeto: S3 cifra el contenido del objeto con la data key en texto plano, luego descarta esa copia en memoria.
- Almacenamiento: S3 guarda el objeto cifrado junto con la data key cifrada (envelope encryption).
- GetObject: S3 llama a KMS
Decryptpara recuperar la data key en texto plano y descifrar el objeto antes de entregarlo al cliente.
Tipos de Claves KMS: Qué Controlas y Qué No
AWS KMS ofrece tres categorías de claves. Para el caso S3, las relevantes son las dos primeras.
AWS Managed Keys son creadas automáticamente la primera vez que usas SSE-KMS en S3 sin especificar una clave. Se identifican con el alias aws/s3. AWS gestiona su rotación anual automáticamente. No puedes modificar su política de clave, no puedes deshabilitarlas, y no puedes usarlas para acceso cross-account. Son gratuitas en términos de costo de clave mensual, pero las llamadas a la API de KMS que S3 genera internamente no se cobran al usuario para este caso específico — AWS absorbe ese costo para sus servicios administrados.
Customer Managed Keys (CMK) las creas tú explícitamente. Tienes control total sobre la key policy, puedes habilitar rotación anual automática, puedes deshabilitarlas o programar su eliminación, y puedes conceder acceso cross-account. Cada llamada a la API de KMS generada por operaciones S3 se cobra a tu cuenta.
Pensar en las AWS Managed Keys como el cerrojo estándar que viene con el apartamento: funciona, cumple su propósito, pero el edificio tiene una copia de la llave maestra y tú no puedes cambiar la cerradura. Una CMK es traer tu propia cerradura — tú decides quién tiene copia.
Costos Asociados a KMS: El Detalle que Importa en Producción
El modelo de costos de KMS tiene dos componentes: el costo mensual por clave almacenada y el costo por llamadas a la API. Los precios exactos varían por región y cambian con el tiempo — siempre verifica la página oficial de precios de AWS KMS.
Lo que sí puedes razonar estructuralmente:
- AWS Managed Keys: Sin costo mensual por la clave. Las llamadas a la API generadas por servicios AWS integrados (como S3 SSE-KMS con aws/s3) no se cobran directamente al usuario.
- CMK — costo mensual: Se cobra por cada clave activa almacenada en KMS, independientemente de si se usa o no.
- CMK — costo por API call: Cada
GenerateDataKey,Decrypt, oGenerateDataKeyWithoutPlaintextcuenta. En un bucket con millones de objetos y acceso frecuente, esto escala rápido. - Capa gratuita: AWS ofrece un número de llamadas gratuitas por mes. Superar ese umbral activa el cargo por llamada.
PutObject / GetObject"] --> B{"Tipo de clave configurada"} B -->|"AWS Managed Key
(aws/s3)"| C["Llamada KMS interna
sin cargo al usuario"] B -->|"Customer Managed Key
(CMK)"| D["Llamada KMS facturable
GenerateDataKey / Decrypt"] D --> E{"Bucket Key
habilitado?"} E -->|"Sí"| F["Llamadas KMS reducidas
S3 agrupa operaciones"] E -->|"No"| G["Una llamada KMS
por objeto accedido"] C --> H["Costo KMS: $0
para el usuario"] F --> I["Costo KMS: reducido
verificar pricing oficial"] G --> J["Costo KMS: escala
con volumen de acceso"]
- Con AWS Managed Key, el costo de API calls para SSE-KMS en S3 no se traslada al usuario — AWS lo absorbe internamente.
- Con CMK, cada lectura y escritura de objeto cifrado genera una llamada facturable a KMS.
- Un bucket con alta frecuencia de acceso puede generar millones de llamadas KMS al mes — estima el volumen antes de elegir CMK.
Cuándo Usar AWS Managed Key
Si tu requisito es cumplimiento básico — datos en reposo cifrados, auditoría en CloudTrail, sin necesidad de control granular sobre la clave — la AWS Managed Key es la opción correcta. Cero overhead operativo, cero costo adicional por la clave, y S3 la gestiona transparentemente.
También es la opción correcta cuando el volumen de operaciones es alto y el presupuesto de KMS no está justificado por un requisito regulatorio específico que exija CMK.
Cuándo Necesitas una CMK
Hay escenarios donde la AWS Managed Key simplemente no alcanza:
- Acceso cross-account: Si una cuenta B necesita leer objetos cifrados en un bucket de la cuenta A, necesitas una CMK en la cuenta A con una key policy que permita acceso a la cuenta B. Las AWS Managed Keys no soportan este patrón.
- Revocación de emergencia: Si necesitas cortar acceso a todos los datos cifrados de forma inmediata — por ejemplo, ante una brecha — deshabilitar una CMK bloquea el descifrado de todos los objetos que la usan, independientemente de las políticas IAM. Con una AWS Managed Key no tienes esa palanca.
- Contexto de cifrado (encryption context): Las CMK permiten usar encryption context para vincular operaciones criptográficas a metadatos específicos, lo que aparece en CloudTrail y permite auditoría más granular.
- Requisitos regulatorios: Algunos marcos como PCI-DSS o FedRAMP en ciertos perfiles requieren que el cliente mantenga control sobre las claves de cifrado.
- Rotación controlada: Aunque AWS Managed Keys rotan automáticamente, no puedes forzar una rotación manual ni controlar el calendario. Con CMK puedes habilitar rotación automática anual o rotar manualmente cuando lo necesites.
Configurar SSE-KMS en S3: AWS Managed Key vs. CMK
Antes de ejecutar estos comandos, verifica que tu rol o usuario tiene los permisos necesarios. Para CMK, necesitas permisos KMS además de S3.
Opción 1: Cifrado con AWS Managed Key (aws/s3)
# Habilitar cifrado por defecto en el bucket usando la AWS Managed Key de S3
aws s3api put-bucket-encryption \
--bucket nombre-de-tu-bucket \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms"
},
"BucketKeyEnabled": true
}
]
}'
Nota: BucketKeyEnabled: true reduce el número de llamadas a KMS al usar una clave de bucket intermedia, lo que disminuye costos cuando usas CMK. Con AWS Managed Key también es recomendable habilitarlo.
Opción 2: Cifrado con Customer Managed Key (CMK)
🔽 Ver comandos completos para CMK
# Paso 1: Crear una CMK simétrica en KMS
aws kms create-key \
--description 'CMK para cifrado de bucket S3 produccion' \
--key-usage ENCRYPT_DECRYPT \
--origin AWS_KMS
# El comando devuelve el KeyId y el ARN de la clave.
# Guarda el ARN para el siguiente paso.
# Paso 2: Crear un alias legible para la clave
aws kms create-alias \
--alias-name 'alias/s3-produccion-cmk' \
--target-key-id 'arn:aws:kms:us-east-1:123456789012:key/tu-key-id'
# Paso 3: Habilitar rotación automática anual
aws kms enable-key-rotation \
--key-id 'arn:aws:kms:us-east-1:123456789012:key/tu-key-id'
# Paso 4: Configurar cifrado por defecto en el bucket con la CMK
aws s3api put-bucket-encryption \
--bucket nombre-de-tu-bucket \
--server-side-encryption-configuration '{
"Rules": [
{
"ApplyServerSideEncryptionByDefault": {
"SSEAlgorithm": "aws:kms",
"KMSMasterKeyID": "arn:aws:kms:us-east-1:123456789012:key/tu-key-id"
},
"BucketKeyEnabled": true
}
]
}'
Verificar la configuración de cifrado
aws s3api get-bucket-encryption \
--bucket nombre-de-tu-bucket
IAM: Permisos Mínimos para Operar con CMK en S3
Este es el punto donde más equipos se bloquean en producción. Tener permisos S3 no es suficiente cuando el bucket usa una CMK — el principal que lee o escribe también necesita permisos KMS. El error típico es un AccessDenied que llega desde KMS, no desde S3, y que los logs de S3 no muestran claramente.
🔽 Ver política IAM mínima para leer/escribir objetos cifrados con CMK
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PermisosS3",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::nombre-de-tu-bucket/*"
},
{
"Sid": "PermisosKMSParaCMK",
"Effect": "Allow",
"Action": [
"kms:GenerateDataKey",
"kms:Decrypt"
],
"Resource": "arn:aws:kms:us-east-1:123456789012:key/tu-key-id"
}
]
}
Además de la política IAM, la key policy de la CMK debe incluir explícitamente al principal como usuario o rol autorizado. Una política IAM que permite kms:Decrypt no es suficiente si la key policy no lo autoriza — KMS evalúa ambas, y ambas deben permitir la acción.
# Verificar la key policy actual de tu CMK
aws kms get-key-policy \
--key-id 'arn:aws:kms:us-east-1:123456789012:key/tu-key-id' \
--policy-name default
El Error que Nadie Anticipa: AccessDenied en Lectura con CMK
El escenario: migras un bucket a CMK, subes objetos sin problema, y al día siguiente un job de procesamiento empieza a fallar con AccessDenied. El equipo revisa las políticas S3 — todo parece correcto. Revisan CloudTrail de S3 — la solicitud ni siquiera llega a S3.
El error real está en CloudTrail de KMS: el rol del job tiene s3:GetObject pero no tiene kms:Decrypt en su política IAM, o tiene el permiso IAM pero no está en la key policy de la CMK. S3 intenta llamar a KMS para descifrar la data key, KMS rechaza la operación, y S3 devuelve AccessDenied al cliente sin contexto adicional.
La corrección siempre requiere dos pasos: agregar el permiso en la política IAM del rol y agregar el principal en la key policy de la CMK. Hacer solo uno de los dos no resuelve el problema.
# Buscar eventos KMS denegados en CloudTrail para diagnosticar
aws cloudtrail lookup-events \
--lookup-attributes AttributeKey=EventName,AttributeValue=Decrypt \
--start-time '2024-01-01T00:00:00Z' \
--end-time '2024-01-02T00:00:00Z'
Bucket Key: Reducir Costos KMS sin Cambiar de Clave
Cuando habilitas S3 Bucket Key (BucketKeyEnabled: true), S3 genera una clave de bucket temporal derivada de tu CMK y la usa para cifrar las data keys de los objetos individuales durante un período corto. Esto reduce drásticamente el número de llamadas directas a KMS — en lugar de una llamada por objeto, S3 agrupa las operaciones.
El resultado observable: el número de llamadas a la API de KMS en CloudTrail y en tus métricas de costos cae significativamente para buckets con alto volumen de escritura. La seguridad no se degrada — la clave de bucket también está cifrada con tu CMK y se rota periódicamente por S3.
Bucket Key es compatible tanto con AWS Managed Keys como con CMK, y se puede habilitar en buckets existentes sin re-cifrar los objetos ya almacenados.
# Verificar si Bucket Key está habilitado
aws s3api get-bucket-encryption \
--bucket nombre-de-tu-bucket \
--query 'ServerSideEncryptionConfiguration.Rules[0].BucketKeyEnabled'
Árbol de Decisión: ¿Qué Tipo de Clave Usar?
necesito para S3?"]) --> Q1{"¿Requieres acceso
cross-account al bucket?"} Q1 -->|"Sí"| CMK1["Customer Managed Key
con key policy cross-account"] Q1 -->|"No"| Q2{"¿Necesitas revocar acceso
a nivel de clave en emergencias?"} Q2 -->|"Sí"| CMK2["Customer Managed Key
deshabilitar clave = acceso bloqueado"] Q2 -->|"No"| Q3{"¿Tienes requisitos regulatorios
que exigen control de clave?"} Q3 -->|"Sí"| CMK3["Customer Managed Key
con rotación y auditoría"] Q3 -->|"No"| AMK["AWS Managed Key (aws/s3)
+ Bucket Key habilitado"] CMK1 --> OPT["Habilitar Bucket Key
si el volumen es alto"] CMK2 --> OPT CMK3 --> OPT
- Si no necesitas control granular ni acceso cross-account, la AWS Managed Key cubre el requisito con cero overhead.
- Si necesitas revocar acceso de emergencia independientemente de IAM, una CMK es el único mecanismo disponible.
- Si el acceso cross-account es un requisito, la CMK con key policy es la única opción viable.
- Si el volumen de operaciones es alto y usas CMK, habilita Bucket Key para controlar el costo de API calls.
Wrap-Up: AWS KMS para S3 en Producción
La elección entre AWS Managed Key y CMK para cifrado en S3 no es una decisión de seguridad binaria — ambas cifran tus datos correctamente. Es una decisión sobre control operativo, modelo de costos y requisitos de cumplimiento. Para la mayoría de los workloads internos sin requisitos regulatorios estrictos, la AWS Managed Key con Bucket Key habilitado es la configuración más práctica. Para datos regulados, acceso cross-account, o escenarios donde necesitas la capacidad de revocar acceso a nivel de clave, una CMK justifica el overhead adicional.
Antes de escalar cualquier solución a producción, estima el volumen de llamadas KMS que generará tu patrón de acceso — ese número define si el costo de CMK es manejable o si necesitas optimizar con Bucket Key.
Recursos oficiales para profundizar:
Glosario de Términos Clave
| Término | Definición |
|---|---|
| SSE-KMS | Server-Side Encryption con AWS KMS. S3 gestiona el cifrado usando claves KMS. |
| Data Key | Clave simétrica generada por KMS para cifrar un objeto específico. Nunca se almacena en texto plano. |
| Envelope Encryption | Patrón donde la data key se cifra con una clave maestra (CMK), y solo la versión cifrada se almacena. |
| Key Policy | Política de acceso adjunta directamente a una clave KMS. Controla quién puede usar o administrar la clave. |
| Bucket Key | Clave temporal derivada de la CMK, generada por S3 para reducir llamadas directas a la API de KMS. |
Comentarios
Publicar un comentario