How to store passwords/credentials in Symfony project(s)
PROBLEM: On a project, I found that the production credentials (users & passwords) were saved in plain text on git repository (actually in parameters.yml.dist) !
Solution: Store sensitive info [credentials (user, pass), API keys, etc.] encrypted in Symfony secrets management system a.k.a Symfony Vault.
The Secrets system requires the Sodium PHP extension.
Implementation
1. Generate Cryptographic Keys
php bin/console secrets:generate-keys
This generate a pair of asymmetric cryptographic keys:
- encrypt key is used for encrypt/add secrets to the vault
Can be safely committed - decrypt key is used to decrypt/read secrets from the vault
The prod decryption key should never be committed
2. Create/encrypt secret
php bin/console secrets:set SECRET_KEY
This command
- encrypts the secret and store the encrypted value in a file (dev.SECRET_KEY.5a8d2d.php)
- add the secret key in the list of secrets (dev.list.php)
3. Use secret in configuration file
In any configuration file use the same syntax as environment variable:
parameters:
lyra.username: '%env(SECRET_KEY)%'
in Controller just dump the parameter:
dd($this->getParameter('lyra.username'));//list the decrypted value
Note: Be careful that you don’t accidentally define a secret and an environment variable with the same name: environment variables override secrets.
4. List the secrets
php bin/console secrets:list
If we have the decrypt file we can “reveal” the value by running:
php bin/console secrets:list --reveal
5. [Optional] Local Values
Remember (from point 3): environment variables override secrets!
The Local Values are environment variables defined in .env.[env].local file!
We can define them manually in .local file OR
run the following command to be set up:
php bin/console secrets:set SECRET_KEY --local
The content of .env.dev.local was updated with:
SECRET_KEY='yyy'
and the list secret command (from step step) also shows the Local value:
6. Deploy
Because the decrypt key is never committed and we need it to decrypt secrets we can:
- upload/copy the production decryption key
OR
- set the
SYMFONY_DECRYPTION_SECRET
environment variable to the base64 encoded value of the production decryption key
Note: The secrets are decrypted on runtime.
In order to improve performance (and avoid decrypting secrets at runtime) we can decrypt secrets during deployment to a “local” vault by running:
php bin/console secrets:decrypt-to-local --force --env=dev
Actually this “local” vault is an .env file (.env.prod.local).
After this file is generated the decrypt key in not needed on server.