tutoriales.com

Asegurando Aplicaciones Serverless: Gestión de Secretos con AWS Secrets Manager

Este tutorial te guiará a través de la gestión segura de secretos en tus aplicaciones serverless utilizando AWS Secrets Manager. Descubrirás cómo almacenar, rotar y recuperar credenciales de forma eficiente y segura, minimizando la exposición de datos sensibles. Ideal para desarrolladores y arquitectos que buscan fortalecer la postura de seguridad de sus sistemas serverless.

Intermedio18 min de lectura12 views
Reportar error

🚀 Introducción a la Seguridad Serverless y la Gestión de Secretos

En el mundo del Cloud Computing y, más específicamente, en la arquitectura Serverless, la seguridad es una preocupación primordial. Las funciones serverless, como AWS Lambda, a menudo necesitan acceder a bases de datos, APIs de terceros, o servicios con credenciales sensibles. La forma en que manejamos estos secretos (contraseñas, claves API, tokens de autenticación) es crítica para evitar brechas de seguridad.

Tradicionalmente, las credenciales se manejaban a menudo como variables de entorno o incrustadas directamente en el código. Sin embargo, estas prácticas son altamente inseguras. Las variables de entorno pueden ser accedidas si la infraestructura es comprometida, y el código con credenciales incrustadas es un riesgo si el repositorio es expuesto.

Aquí es donde entra en juego AWS Secrets Manager, un servicio de AWS diseñado para ayudarte a almacenar, administrar y recuperar secretos de forma segura. Permite proteger el acceso a tus aplicaciones, servicios y recursos de TI sin la necesidad de incrustar las credenciales directamente en el código.

¿Por qué AWS Secrets Manager? 🤔

AWS Secrets Manager ofrece una serie de ventajas clave para la gestión de secretos en entornos serverless:

  • Seguridad Mejorada: Los secretos se cifran en reposo utilizando AWS Key Management Service (KMS) y en tránsito utilizando TLS.
  • Rotación Automática: Permite la rotación automática de secretos, lo que reduce el riesgo de credenciales comprometidas y cumple con las mejores prácticas de seguridad.
  • Control de Acceso Fino: Integración con AWS Identity and Access Management (IAM) para controlar quién puede acceder a qué secreto y bajo qué condiciones.
  • Auditoría: Se integra con AWS CloudTrail para registrar todos los eventos de acceso a los secretos, proporcionando un rastro de auditoría completo.
  • Reducción de la Deuda Técnica: Elimina la necesidad de escribir código personalizado para manejar la rotación de credenciales.
🔥 Importante: Nunca uses credenciales codificadas o variables de entorno no cifradas para secretos sensibles en producción. AWS Secrets Manager es la solución recomendada para este propósito.

🛠️ Conceptos Clave de AWS Secrets Manager

Antes de sumergirnos en la implementación, es crucial entender los componentes principales de AWS Secrets Manager.

📖 Secretos (Secrets)

Un secreto en Secrets Manager es un registro de credenciales (o cualquier otra información sensible) que deseas proteger. Puede ser una contraseña, una clave API, un par de claves SSH, etc. Un secreto puede contener múltiples valores (por ejemplo, nombre de usuario y contraseña) y se almacena como texto sin formato o binario.

🔄 Rotación (Rotation)

La rotación de secretos es el proceso de cambiar las credenciales de un secreto periódicamente. Secrets Manager puede automatizar este proceso para bases de datos (como Amazon RDS, Amazon Aurora, Amazon Redshift), servicios (como Amazon DocumentDB) y otros secretos personalizados. Esto es fundamental para la seguridad, ya que las credenciales de larga duración son un riesgo.

🔑 AWS KMS (Key Management Service)

Secrets Manager utiliza AWS KMS para cifrar los secretos en reposo. Cuando creas un secreto, puedes elegir una clave KMS administrada por AWS o una clave KMS personalizada que tú administras. Esto añade una capa extra de seguridad y control.

🛡️ Políticas de Recursos (Resource Policies)

Al igual que con otros recursos de AWS, puedes adjuntar políticas de recursos a tus secretos en Secrets Manager. Estas políticas, junto con las políticas de IAM, determinan quién puede realizar qué acciones sobre un secreto específico.

Diagrama de Flujo General 📈

Desarrollador Crea y Almacena Secreto AWS Secrets Manager Gestión de Secretos (Cifrado en reposo) AWS KMS Llaves de Cifrado AWS Lambda App Serverless Base de Datos / Recurso Acceso Seguro 1. Almacenar 2 & 4. Cifrar/Descifrar 3. Solicita Secreto 4. Entrega Secreto 5. Acceso con Credenciales

🚀 Primeros Pasos: Almacenar un Secreto en AWS Secrets Manager

Vamos a empezar por la tarea más básica: almacenar un secreto. Para este tutorial, asumiremos que tienes una cuenta de AWS y acceso a la consola de AWS.

Paso 1: Navegar a AWS Secrets Manager

  1. Inicia sesión en la Consola de AWS.
  2. En la barra de búsqueda, escribe Secrets Manager y selecciona el servicio.
  3. Haz clic en el botón Almacenar un nuevo secreto.

Paso 2: Configurar el Tipo de Secreto

Secrets Manager ofrece plantillas para diferentes tipos de secretos. Selecciona el que mejor se adapte a tus necesidades. Para nuestro ejemplo, vamos a almacenar credenciales para una base de datos PostgreSQL.

  1. Tipo de Secreto: Selecciona Credenciales para base de datos RDS, Redshift o DocumentDB.
  2. Credenciales: Ingresa el Nombre de usuario (ej: admin) y la Contraseña (ej: SuperSecretP@ssw0rd!).
  3. Base de datos: Puedes elegir una instancia RDS existente o dejarlo sin especificar si es para una DB externa o si no quieres asociarlo aún.
  4. Haz clic en Siguiente.
💡 Consejo: Para contraseñas, usa una combinación de letras mayúsculas y minúsculas, números y símbolos para maximizar la seguridad.

Paso 3: Detalles del Secreto

Ahora, proporciona un nombre y una descripción para tu secreto.

  1. Nombre del Secreto: Ingresa un nombre descriptivo, por ejemplo, /my-serverless-app/db-credentials.
    • Importante: Es una buena práctica usar una convención de nomenclatura que incluya el nombre de la aplicación o entorno.
  2. Descripción: Añade una descripción útil (ej: Credenciales de la base de datos para la aplicación serverless).
  3. Haz clic en Siguiente.

Paso 4: Configurar la Rotación (Opcional por ahora)

La rotación es una característica poderosa, pero la configuraremos más adelante en detalle. Por ahora, desactívala.

  1. Configurar rotación automática: Selecciona Deshabilitar la rotación automática.
  2. Haz clic en Siguiente.

Paso 5: Revisar y Almacenar

Revisa todos los detalles y luego almacena el secreto.

  1. Verifica la configuración del secreto.
  2. Haz clic en Almacenar.

¡Felicidades! Has almacenado tu primer secreto en AWS Secrets Manager. Ahora, veremos cómo recuperarlo desde una función AWS Lambda.


💻 Recuperando Secretos desde AWS Lambda

Una vez que el secreto está almacenado, el siguiente paso es que nuestra aplicación serverless (en este caso, una función AWS Lambda) pueda acceder a él de forma segura. Para esto, usaremos el SDK de AWS.

Paso 1: Crear una Función Lambda

Vamos a crear una función Lambda sencilla que intente recuperar el secreto.

  1. En la Consola de AWS, navega a Lambda.
  2. Haz clic en Crear función.
  3. Nombre de la función: MySecretReaderFunction.
  4. Runtime: Selecciona Python 3.9 (o la versión que prefieras).
  5. Permisos: En Cambiar el rol de ejecución predeterminado, selecciona Crear un rol nuevo con permisos básicos de Lambda.
  6. Haz clic en Crear función.

Paso 2: Actualizar la Política de Permisos del Rol de Lambda

La función Lambda necesitará permisos para llamar a la API de Secrets Manager (secretsmanager:GetSecretValue).

  1. Una vez creada la función, ve a la pestaña Configuración y luego a Permisos.
  2. Haz clic en el Nombre del rol de ejecución (ej: MySecretReaderFunction-role-xxxxxx). Esto te llevará a la consola de IAM.
  3. En la página del rol de IAM, haz clic en Agregar permisos -> Crear política insertada.
  4. Selecciona la pestaña JSON y pega la siguiente política:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "secretsmanager:GetSecretValue",
            "Resource": "arn:aws:secretsmanager:<YOUR_REGION>:<YOUR_ACCOUNT_ID>:secret:/my-serverless-app/db-credentials-*"
        }
    ]
}
  1. ¡Importante! Reemplaza <YOUR_REGION> y <YOUR_ACCOUNT_ID> con tu región y ID de cuenta reales. El * al final del ARN del secreto permite que la función acceda a diferentes versiones del secreto, lo cual es útil para la rotación.
  2. Haz clic en Revisar política.
  3. Nombre: Dale un nombre a la política, por ejemplo, SecretsManagerAccessPolicy.
  4. Haz clic en Crear política.
📌 Nota: Es una buena práctica otorgar el menor privilegio posible. Especifica el ARN exacto del secreto en lugar de un `*` si sabes que la función solo necesita acceso a un secreto específico.

Paso 3: Escribir el Código de la Función Lambda

Ahora, actualizaremos el código de la función Lambda para recuperar el secreto.

  1. Vuelve a la consola de Lambda, en la pestaña Código de tu función MySecretReaderFunction.
  2. Reemplaza el código existente con el siguiente código Python:
import json
import boto3
from botocore.exceptions import ClientError

def get_secret():
    secret_name = "/my-serverless-app/db-credentials"
    region_name = "<YOUR_REGION>" # Asegúrate de que esta sea tu región

    # Crea un cliente de Secrets Manager
    client = boto3.client(service_name='secretsmanager', region_name=region_name)

    try:
        get_secret_value_response = client.get_secret_value(SecretId=secret_name)
    except ClientError as e:
        # Maneja diferentes errores posibles
        if e.response['Error']['Code'] == 'DecryptionFailureException':
            # Secrets Manager no puede descifrar el secreto usando la clave KMS especificada.
            raise e
        elif e.response['Error']['Code'] == 'InternalServiceErrorException':
            # Ocurrió un error en el servidor de Secrets Manager.
            raise e
        elif e.response['Error']['Code'] == 'InvalidParameterException':
            # Parámetro de solicitud inválido.
            raise e
        elif e.response['Error']['Code'] == 'InvalidRequestException':
            # La solicitud no es válida para el estado actual del secreto.
            raise e
        elif e.response['Error']['Code'] == 'ResourceNotFoundException':
            # El secreto solicitado no fue encontrado.
            raise e
    else:
        # Decodifica el secreto para poder usarlo
        if 'SecretString' in get_secret_value_response:
            secret = get_secret_value_response['SecretString']
            return json.loads(secret)
        else:
            # Si el secreto es binario, tendrás que decodificarlo de base64
            decoded_binary_secret = base64.b64decode(get_secret_value_response['SecretBinary'])
            return decoded_binary_secret

def lambda_handler(event, context):
    try:
        db_credentials = get_secret()
        username = db_credentials['username']
        password = db_credentials['password']
        
        print(f"Usuario de la base de datos: {username}")
        print(f"Contraseña de la base de datos: {password}") # ¡En un entorno real, no imprimas esto!
        
        # Aquí es donde usarías las credenciales para conectar a tu base de datos o servicio
        # Ejemplo: db_connection = connect_to_db(username, password)

        return {
            'statusCode': 200,
            'body': json.dumps('Credenciales recuperadas y usadas (ver logs).')
        }
    except Exception as e:
        print(f"Error al recuperar o usar el secreto: {e}")
        return {
            'statusCode': 500,
            'body': json.dumps(f'Error: {str(e)}')
        }
  1. ¡Importante! Reemplaza <YOUR_REGION> con tu región de AWS.
  2. Haz clic en Deploy para guardar los cambios.

Paso 4: Probar la Función Lambda

  1. En la consola de Lambda, haz clic en Test.
  2. Crea un nuevo evento de prueba con cualquier nombre (ej: MyTestEvent) y usa la plantilla hello-world predeterminada.
  3. Haz clic en Guardar y luego en Test.
  4. Verás los resultados de la ejecución. En la pestaña Log output, deberías ver las credenciales impresas (recuerda: NO hagas esto en producción).
⚠️ Advertencia: NUNCA imprimas secretos directamente en los logs en un entorno de producción. Los `print` en este ejemplo son solo para demostración. Utiliza las credenciales de forma segura dentro de tu lógica de negocio.

🔄 Configurando la Rotación Automática de Secretos

La rotación automática es una de las características más potentes de AWS Secrets Manager. Reduce significativamente la superficie de ataque al asegurar que las credenciales cambian regularmente.

¿Cómo funciona la rotación? 🤔

Secrets Manager utiliza una función Lambda para rotar los secretos. Cuando configuras la rotación, Secrets Manager crea y gestiona esta función Lambda de rotación, y establece un disparador de CloudWatch Events para invocarla periódicamente.

CloudWatch Events (Programador) Función Lambda de Rotación Secrets Manager (Almacén de Secretos) Base de Datos (Actualización Usuario) 2. Dispara 4. Cambia contraseña 5. Actualiza Obtiene viejo 1 2 3 4 5

Paso 1: Habilitar la Rotación para un Secreto Existente

  1. Navega a la consola de Secrets Manager.
  2. Selecciona el secreto que creaste anteriormente (ej: /my-serverless-app/db-credentials).
  3. En la sección Detalles del secreto, haz clic en Editar rotación.
  4. Habilitar rotación automática: Marca la casilla Habilitar rotación automática.
  5. Frecuencia de rotación: Establece la frecuencia deseada (ej: cada 30 días).
  6. Función de rotación: Selecciona Crear una nueva función de rotación Lambda. Esto creará una función Lambda preconfigurada para rotar las credenciales.
  7. Rol de ejecución: Deja la opción para que Secrets Manager cree un nuevo rol de IAM para la función de rotación.
  8. Base de datos: Aquí es donde especificarás la instancia de base de datos a la que pertenecen las credenciales. Si seleccionaste Credenciales para base de datos RDS... al crear el secreto, verás un desplegable con tus instancias RDS. Selecciona la instancia db-instance-1 (o la que corresponda a tu secreto).
  9. Haz clic en Guardar.

Secrets Manager ahora creará la función Lambda de rotación y configurará todo lo necesario. Este proceso puede tardar unos minutos.

🔥 Importante: Asegúrate de que la función Lambda de rotación tenga los permisos adecuados para conectarse a tu base de datos y cambiar la contraseña del usuario especificado en el secreto. Secrets Manager generalmente configura esto automáticamente para bases de datos AWS compatibles.

Paso 2: Probar la Rotación (Opcional)

Puedes probar la rotación inmediatamente para verificar que funciona correctamente:

  1. En la página de detalles del secreto, haz clic en el botón Rotar secreto ahora.
  2. Esto invocará la función de rotación y cambiará las credenciales en la base de datos y en Secrets Manager.
  3. Puedes monitorear el progreso en los logs de la función Lambda de rotación (disponible en CloudWatch Logs).
💡 Consejo: Siempre prueba la rotación en un entorno de desarrollo antes de implementarla en producción para evitar interrupciones.

🔐 Mejores Prácticas y Consideraciones Adicionales

Para maximizar la seguridad y la eficiencia al usar AWS Secrets Manager en tus arquitecturas serverless, considera estas mejores prácticas:

1. Principio de Mínimo Privilegio (Least Privilege) ✅

  • Otorga solo los permisos necesarios a tus funciones Lambda para acceder a los secretos específicos que requieren. Evita Resource: "*" siempre que sea posible.
  • Utiliza políticas de IAM detalladas para secretsmanager:GetSecretValue con el ARN exacto del secreto.

2. Caching de Secretos 💨

  • Recuperar un secreto de Secrets Manager implica una llamada a la API, lo que añade latencia y puede generar costos adicionales en invocaciones frecuentes.
  • Considera implementar un mecanismo de caching para los secretos dentro de tu función Lambda si los secretos no cambian con cada invocación.
    • Ejemplo: Almacena el secreto recuperado en una variable global fuera del lambda_handler para que se reutilice en invocaciones en caliente (warm invocations).
import json
import boto3
from botocore.exceptions import ClientError

# Variable global para cachear el secreto
CACHED_SECRET = None

def get_secret():
    global CACHED_SECRET
    
    if CACHED_SECRET:
        return CACHED_SECRET

    secret_name = "/my-serverless-app/db-credentials"
    region_name = "<YOUR_REGION>"

    client = boto3.client(service_name='secretsmanager', region_name=region_name)

    try:
        get_secret_value_response = client.get_secret_value(SecretId=secret_name)
        if 'SecretString' in get_secret_value_response:
            secret_dict = json.loads(get_secret_value_response['SecretString'])
            CACHED_SECRET = secret_dict # Cachea el secreto
            return secret_dict
        else:
            # Manejo para secretos binarios
            pass # ...
    except ClientError as e:
        # Manejo de errores
        raise e

def lambda_handler(event, context):
    # ... (resto de la lógica usa get_secret() )
    pass
⚠️ Advertencia: Si los secretos rotan frecuentemente y tu caching es de larga duración, podrías estar usando un secreto obsoleto. Ajusta la estrategia de caching según la frecuencia de rotación.

3. Monitoreo y Auditoría 🕵️‍♂️

  • Configura alarmas de Amazon CloudWatch para monitorear los eventos de Secrets Manager (ej: fallos de rotación, intentos de acceso no autorizados).
  • Utiliza AWS CloudTrail para auditar todas las API calls realizadas a Secrets Manager. Esto te permite saber quién accedió a qué secreto y cuándo.

4. Gestión del Ciclo de Vida del Secreto 🗑️

  • Cuando un secreto ya no es necesario, elimínalo de Secrets Manager. Secrets Manager ofrece un período de recuperación configurable (predeterminado de 30 días) antes de la eliminación permanente, lo que te da tiempo para restaurarlo si fue eliminado por error.

5. Uso de Tags 🏷️

  • Aplica tags a tus secretos para organizarlos, gestionarlos y aplicar políticas basadas en tags (por ejemplo, para controlar quién puede rotar secretos de producción).

6. Integración con CI/CD 🚀

  • Integra la creación y gestión de secretos en tus pipelines de CI/CD para automatizar el aprovisionamiento y asegurarte de que los secretos se manejan de forma coherente y segura en todos los entornos.

📊 Comparativa con AWS Systems Manager Parameter Store

Es común confundir AWS Secrets Manager con AWS Systems Manager Parameter Store. Ambos servicios almacenan información de configuración y credenciales, pero tienen propósitos ligeramente diferentes.

CaracterísticaAWS Secrets ManagerAWS Systems Manager Parameter Store
---------
Propósito PrincipalAlmacenamiento y rotación de secretos (credenciales)Almacenamiento de datos de configuración y valores no sensibles
Rotación Automática✅ Sí (para DBs, servicios, personalizados)❌ No
---------
CostoBasado en el número de secretos y API calls (más caro)Niveles Estándar (gratuito), Avanzado (costo)
CifradoSiempre cifrado con KMSOpcionalmente cifrado con KMS
---------
AuditoríaCloudTrailCloudTrail
Tipo de Datos TípicoContraseñas, claves API, tokensURLs de bases de datos, nombres de usuario, flags de características, strings de conexión
---------
Uso IdealCredenciales de BD, tokens OAuth, claves APINombres de base de datos, puertos, niveles de log
90% Seguridad Crítica
70% Configuración General

En resumen, si la información es sensible y necesita rotación periódica, AWS Secrets Manager es la elección correcta. Si es configuración general o datos menos sensibles que no requieren rotación, Parameter Store es una alternativa más económica y adecuada.


Conclusión ✨

La gestión segura de secretos es un pilar fundamental en cualquier arquitectura, y más aún en los entornos serverless donde la inmutabilidad y la efimeridad son la norma. AWS Secrets Manager proporciona una solución robusta y escalable para proteger tus credenciales, automatizar su rotación y auditar su acceso, permitiéndote construir aplicaciones serverless más seguras y resilientes.

Al integrar Secrets Manager en tus funciones Lambda, no solo cumples con las mejores prácticas de seguridad, sino que también reduces la complejidad operativa y te aseguras de que tus datos más sensibles estén protegidos en todo momento.

¡Esperamos que este tutorial te haya sido de gran utilidad para empezar a asegurar tus aplicaciones serverless con AWS Secrets Manager! Si tienes alguna pregunta, no dudes en explorar la documentación oficial de AWS.

Tutoriales relacionados

Comentarios (0)

Aún no hay comentarios. ¡Sé el primero!