How to store passwords/credentials in Symfony project(s)

Cosmin Sandu
3 min readOct 4, 2022

--

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

output of 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
Git status after php bin/console secrets:generate-keys

2. Create/encrypt secret

php bin/console secrets:set SECRET_KEY

Output of 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)
git status after adding new secret

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
output of php bin/console secrets:list

If we have the decrypt file we can “reveal” the value by running:

php bin/console secrets:list --reveal
output of 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
output of 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:

output of php bin/console secrets:list --reveal

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.

--

--