La Bóveda de los Secretos
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
With a Subscription, click any sentence in the script to jump to that part of the video!
Login SubscribeNo quiero adentrarme demasiado en el despliegue, pero vamos a hacer un curso rápido de "Cómo desplegar tu aplicación Symfony 101". Esta es la idea.
Despliegue 101
Paso 1: Tienes que llevar de alguna manera todo tu código comprometido a tu máquina de producción y luego ejecutar
composer install
para rellenar el directorio vendor/.
Paso 2: crea de algún modo un archivo .env.local con todas tus variables de entorno de producción, que incluirá APP_ENV=prod, para que estés en el entorno de producción.
Y Paso 3: ejecuta
php bin/console cache:clear
que borrará la caché en el entorno de producción, y luego
php bin/console cache:warmup
para "calentar" la caché. Puede haber algunos otros comandos, como ejecutar las migraciones de tu base de datos... pero esta es la idea general. Y los documentos de Symfony tienen más detalles.
Por cierto, en caso de que te lo preguntes, desplegamos a través de https://platform.sh, utilizando la integración en la nube de Symfony... que se encarga de muchas cosas por nosotros. Puedes comprobarlo entrando en https://symfony.com/cloud. También ayuda a apoyar el proyecto Symfony, así que todos salimos ganando.
Utiliza variables de entorno reales cuando sea posible
De todos modos, la parte más complicada del proceso es el paso 2: crear el archivo .env.localcon todos tus valores de producción, que incluirán cosas como las claves de la API, los detalles de la conexión a la base de datos y más.
Ahora bien, si tu plataforma de alojamiento te permite almacenar variables de entorno reales directamente dentro de ella, ¡problema resuelto! Si estableces variables de entorno reales, entonces no hay necesidad de gestionar un archivo .env.local en absoluto. En cuanto despliegues, Symfony verá y utilizará instantáneamente las variables de entorno reales. Eso es lo que hacemos para Symfonycasts.
¿Crear el .env.local durante el despliegue?
Pero si eso no es una opción para ti, tendrás que dar de alguna manera a tu sistema de despliegue acceso a tus valores sensibles para que pueda crear el archivo.env.local. Pero... como no vamos a consignar ninguno de estos valores en nuestro repositorio, ¿dónde debemos almacenarlos?
Una opción para manejar los valores sensibles es la bóveda de secretos de Symfony. Es un conjunto de archivos que contienen variables de entorno de forma encriptada. Estos archivos son seguros para enviarlos a tu repositorio... ¡porque están encriptados!
Creando la Bóveda dev
Si quieres almacenar secretos en una bóveda, necesitarás dos: una para el entornodev y otra para el entorno prod. Primero vamos a crear estas dos bóvedas... y luego te explicaré cómo leer valores de ellas.
Empieza creando una para el entorno dev. Ejecuta:
php bin/console secrets:set
Pasa este GITHUB_TOKEN, que es el secreto que queremos establecer. A continuación, nos pide nuestro "valor secreto". Como se trata de la bóveda del entorno dev, queremos poner algo que sea seguro para que todos lo vean. En un momento explicaré por qué. Diré CHANGEME. No puedes verme escribir eso... sólo porque Symfony lo oculta por razones de seguridad.
Como este es el primer secreto que hemos creado, Symfony creó automáticamente la bóveda de secretos entre bastidores... que es literalmente un conjunto de archivos que viven en config/secrets/dev/. Para la bóveda dev, vamos a confirmar todos estos archivos en el repositorio. Vamos a hacerlo. Añade todo el directorio de secretos:
git add config/secrets/dev
Luego haz el commit con:
git commit -m "adding dev secrets vault"
Los archivos de la bóveda de secretos
He aquí una explicación rápida de los archivos. dev.list.php almacena una lista de los valores que viven dentro de la bóveda, dev.GITHUB_TOKEN.28bd2f.php almacena el valor cifrado real, y dev.encrypt.public.php es la clave criptográfica que permite a los desarrolladores de tu equipo añadir más secretos. De modo que si otro desarrollador se baja del proyecto, tendrá este archivo... para poder añadir más secretos. Por último, dev.decrypt.private.php es la clave secreta que nos permite desencriptar y leer los valores de la bóveda.
En cuanto los archivos de la bóveda estén presentes, Symfony los abrirá automáticamente, descifrará los secretos y los expondrá como variables de entorno Pero, más sobre esto en unos minutos.
¿Acervar la clave de desencriptación dev?
Pero espera: ¿realmente acabamos de confirmar la clave decrypt en el repositorio? Sí, ¡eso normalmente sería un no-no! ¿Por qué te tomarías la molestia de encriptar valores... sólo para almacenar la clave de desencriptación junto a ellos?
La razón por la que hacemos esto es que se trata de nuestra bóveda de desarrollo, lo que significa que sólo vamos a almacenar valores que sean seguros para que los vean todos los desarrolladores. La bóveda de dev sólo se utilizará para el desarrollo local... y queremos que nuestros compañeros de equipo puedan bajar el código y leerlo sin problemas.
Bien, en este punto tenemos una bóveda dev que Symfony utilizará automáticamente en el entorno dev. Siguiente: vamos a crear la bóveda prod, que contendrá los valores verdaderamente secretos. Luego aprenderemos la relación entre los secretos de la bóveda y las variables de entorno... así como una forma fácil de visualizar todo esto.
13 Comments
Hi all,
I've been trying to use the base64 encrypted version of my private key for the secrets vault and I must be missing something. I have encrypted the password according to the docs
php -r 'echo base64_encode(require "config/secrets/prod/prod.decrypt.private.php");'and set that value on the server as an environment variable SYMFONY_DECRYPTION_SECRET but the app still doesn't find the variables in the vault.
Am I missing something obvious?
Thanks!
Seems it was obvious. For anybody as thick as me that ends up with the same quandary, the SYMFONY_DECRYPTION_SECRET needs to be in the .env file and not a server environment variable.
Hey @phpbutcher
I'd need to double-check but as far as I know, you should be able to set it as a server env var. Is it possible that you were overriding its value in the
.envor.env.localfile?Cheers!
So I know I must be missing something simple but I've read the docs and I either missed it or I'm just not getting it. I was under the impression that once I added a variable to the secrets vault it would be available in my controller as $_ENV['MY_SECRET_VARIABLE'] but that doesn't seem to be the case. The only references I've seen in the doc were to use them in config files with '%env(MY_SECRET_VARIABLE)%'.
I'm hoping someone can explain either what I'm missing in the docs or what I need to do to use the secret variables directly in my controllers.
Thanks for any help
Hey @phpbutcher!
Yea, this is a good question. The secrets become "environment variables in Symfony", but I'm pretty sure that they're not written back to
$_ENV(and your experience confirms that). But to answer your question, to use a value directly in your controller, I would:That should do it :). The
Autowireattribute is relatively new (theenvargument is even newer), but this can be used for controller args or the__construct()method in any service.Let me know if that helps!
Cheers!
Thanks for the reply Ryan!
That would be an awesome suggestion except I lied a little in my OP. Some of the secret variables I am indeed trying to use in a controller that extends AbstractController but some are not. I did manage to solve my problem in those cases this morning by binding them in /config/services.yaml. I originally thought that wasn't working because I put the bind in like so ( for the future benefit of others like me) and it threw an error because it seems as soon as you put a bind variable in services.yaml it has to be used somewhere and I hadn't done that yet.
And then in my LoginFormAuthenticator class:
If there's a better/easier way to do it I'd love to hear it.
Thanks again Ryan! I will make use of the Autowire(env: thing in my Controllers. It makes it much more obvious to others where that value is coming from.
Ryan,
It seems I didn't read your reply close enough. Your Autowire suggestion does work in both the Controller and LoginFormAuthenticator.
Thanks for taking the time to Respond. It makes the Symfony Casts so much more valuable.
Sweeet! Super happy it worked!
A tutorial on deployment might be an interesting idea :)
Hey Rufnex,
We do have a tutorial about deployment already! :) Take a look at Ansistrano tool: https://symfonycasts.com/screencast/ansistrano - it's based on Ansible automation language, but you're not required to know it to start this deployment course as its syntax is pretty descriptive. Moreover we explain it during the course well I think. But in case you're interested in Ansible to learn its syntax deeper - we also have a separate tutorial about it here: https://symfonycasts.com/screencast/ansible
Cheers!
Thank you Victor. I will check it out.
Hey Rufnex,
You're welcome! If you have any use cases that are not covered with that Ansistrano deploy tutorial - please, let us know in the comments! It would definitely help us to plan a new deploy tutorial in the future :)
Cheers!
Hey,
Thanks for the feedback, I'll put your idea in our list =)
Cheers!
"Houston: no signs of life"
Start the conversation!