AWS Secrets Manager for Spring Boot credential management

En el ámbito del desarrollo de aplicaciones, se podría entender por seguridad como ese conjunto de tormentosas restricciones a cumplir unas pocas semanas antes de salir a producción, que obligan a modificar buena parte del código fuente, y que frecuentemente viene acompañada de fuertes dolores de cabeza, además de una buena ración de horas extras. Puede ser que la definición no sea del todo precisa, o puede que sí, al fin y al cabo, vivimos en un mundo de grises dominado por los matices, pero la premisa es clara.

Bromas aparte y para decepción de muchos, este artículo no proporciona la fórmula mágica para evitar que una definición a todas luces caricaturesca deje de ser una realidad en cientos de organizaciones del mundo entero. El ámbito del escrito es algo más reducido, en concreto, como gestionar de forma segura las credenciales de una aplicación Spring Boot mediante AWS Secrets Manager, pero Roma tampoco se construyó en un día.

Caso de uso

Se dispone de una cluster de EKS en el que se quiere desplegar un microservicio Spring Boot que implementa operaciones CRUD sobre una AWS RDS de tipo PostgreSQL, gestionando las credenciales de forma segura mediante AWS Secrets Manager.

AWS Secrets Manager

Tal y como reza la documentación oficial de AWS, Secrets Manager es un servicio de administración de datos confidenciales que permite alternar, administrar y recuperar fácilmente credenciales de bases de datos, claves de API y otros datos confidenciales durante todo su ciclo de vida, en un documento JSON de hasta 64KB. En este caso, no hay mucho aclarar, si bien la traducción al castellano es mejorable.

Destaca la posibilidad rotar de forma automatizada y programada las credenciales para algunos sistemas como Amazon Relational Database Service (RDS), Amazon DocumentDB y Amazon Redshift, cumpliendo así con las buenas practicas de seguridad para garantizar una mayor protección. Sobra decir que esto no tiene impacto alguno en las aplicaciones, ya que el proceso de autenticación se produce a la hora de establecer la conexión con la base de datos.

Sus principales virtudes son la facilidad de uso, su reducido coste (0,40$ por secreto + 0,05$ por cada 10.000 llamadas a la API) y como no podía ser de otra forma, su integración con los servicios propios de la nube.

AWS RDS Secret Management

Dejando de lado una descripción más propagandística de la cuenta, y una vez detallado que es el Secrets Manager, es hora de crear un secreto con las credenciales de una AWS RDS y rotación periódica, para que posteriormente pueda ser consumido por el microservicio Spring Boot.

Si bien es posible llevar a cabo este proceso via IaC, ya sea con CloudFormation o Terraform, entre otros, en este escrito se detallarán los pasos a seguir mediante la AWS Console. Así, lo primero es acceder al formulario de creación de secretos ubicado en Services → Secrets Manager → Secrets → Store a new secret.

En este punto, es necesario seleccionar el tipo de secreto como Credentials for RDS database, especificar un usuario y password, y finalmente seleccionar la base de datos de destino. La clave de encriptación por defecto es una opción valida y segura, si bien dependiendo de la organización y de las políticas de seguridad de esta, puede requerir que se gestione de forma específica.

En el siguiente formulario se solicita dar un nombre al secreto y es recomendable pero no imprescindible que este empiece por “/secret/”, para simplificar después la configuración a aplicar a nivel de microservicio. El resto de las cuestiones son opcionales y es decisión de cada organización como configurarlas.

Por último, no queda más que especificar la política de rotación del secreto. Para ello, es necesario habilitar dicha opción, configurar un tiempo de vida máximo y dar un nombre a la función Lambda encargada de llevar a cabo la tarea. También es posible crear una función personalizada que se encargue del proceso, pero no merece la pena para el caso de uso descrito.

Si nada ha interferido en el proceso, el secreto debería ser visible a través de la AWS Console en Services → Secrets Manager → Secrets.

Es posible conocer el contenido del mismo a través de la AWS Console en Services → Secrets Manager → Secrets -> /secret/test-rds-postgresql -> Retrieve secret value, siempre y cuando el usuario disponga de los permisos requeridos. Prestad atención a los nombres de las claves, ya que serán los que posteriormente se utilicen a la hora de configurar la conexión a la base de datos por parte de la aplicación.

Spring Boot Secret Management

Llegó la hora de configurar el microservicio Spring Boot para leer los secretos en el arranque, lo que por fortuna es un proceso mucho más sencillo de lo que cabria esperar.

Lo primero de todo es añadir la dependencia spring-cloud-starter-aws-secrets-manager-config al fichero pom.xml de la aplicación.

		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-aws-secrets-manager-config</artifactId>
            <version>2.2.6.RELEASE</version>
		</dependency>

Esta librería se encarga de recoger automáticamente dos secretos, uno común y uno especifico de aplicación, en base a la configuración especificada en el fichero bootstrap.yaml. Dado que únicamente se ha creado un secreto especifico de la aplicación, la configuración a introducir seria la siguiente, si bien en la documentación oficial se proporciona una descripción para cada uno de los parámetros configurables.

aws:
  secretsmanager:
    name: test-rds-postgresql

Para deshabilitar este comportamiento en un entorno local, basta con crear un fichero bootstrap-local.yaml, con la propiedad enabled a false. Sobra decir, que la aplicación debe se ejecutada con el perfil local de Spring activo.

aws:
  secretsmanager:
    enabled: false

Dicho esto, la librería se encarga de leer en el arranque todos los valores almacenados en el secreto especificado, añadiendo el prefijo /secret/ (esto también es configurable), y convertirlos en variables de entorno, que pueden ser utilizados en los ficheros de configuración de Spring como los application.yaml.

    spring:
      datasource:
        driver-class-name: org.postgresql.Driver
        url: jdbc:postgresql://${host}:{port}/${dbname}
        username: ${username}
        password: ${password}
      jpa:
        database-platform: org.hibernate.dialect.PostgreSQL9Dialect
        properties:
          hibernate:
            dialect: org.hibernate.dialect.PostgreSQLDialect

Finalmente, comentar qué para poder acceder al AWS Secrets Manager, el microservicio deberá disponer de un AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY con el que identificarse, los cuales pueden ser inyectados como variables de entorno.

Conclusiones

En conclusión, AWS Secrets Manager es un servicio de administración de datos confidenciales que permite alternar, administrar y recuperar fácilmente credenciales de bases de datos, claves de API y otros datos confidenciales. Las aplicaciones Sprint Boot pueden integrarse fácilmente con el haciendo uso de la libreria spring-cloud-starter-aws-secrets-manager-config.

Ahora bien, tened en cuenta que en el artículo se muestra un caso de uso muy muy sencillo con un único secreto de base de datos que puede servir como punto partida, pero la librería esta preparada para leer hasta dos secretos distintos, uno propio de aplicación y otro común para servicios compartidos, que bien pueden albergar información de múltiples fuentes de datos.

Referencias

Se recomienda encarecidamente leer los siguientes artículos que han servido de base para el escrito:

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s