Using & Overriding Secrets
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 SubscribeWe have successfully added the SENTRY_DSN
secret value to both the dev
and prod
vaults.
Listing the Secrets
How can I prove that? By running:
php bin/console secrets:list
Because we're in the dev
environment, this reads the dev
vault. There's our one secret. To see its value, add --reveal
:
php bin/console secrets:list --reveal
Behind-the-scenes, that used the dev "decrypt" key to decrypt the value: it's an empty string. Ignore this "local value" thing for a minute.
We can do the same thing for the prod
vault by passing --env=prod
:
php bin/console secrets:list --env=prod
Including adding --reveal
to see the value.
php bin/console secrets:list --env=prod --reveal
Reading Secrets in your App
Ok: because we're in the dev
environment, the dev
secret - the empty string - is the one that should be used. Refresh the page, check the dump, and expand it a few times. It's still using the production value.
Go back into config/packages/sentry.yaml
:
sentry: | |
dsn: '%env(SENTRY_DSN)%' |
We're still using the syntax for reading environment variables. How can we tell it to read the SENTRY_DSN
secret instead? Surprise! To tell Symfony to read a SENTRY_DSN
secret, we use the exact same syntax.
Environment Variables vs Secrets
Let me explain: when Symfony sees the %env()%
syntax, it first looks to see if an environment variable called SENTRY_DSN
exists. If it does, it uses it. If there is not, it then looks for a secret in the vault called SENTRY_DSN
. So reading environment variables and secrets uses the same syntax, but environment variables take priority.
This means one important thing: when you identify an environment variable that you want to convert into a secret, you need to remove it entirely as an environment variable. Set a value as an environment variable or a secret, but not both. Delete the SENTRY_DSN
entry from .env
and .env.local
:
// ... lines 1 - 22 | |
###> sentry/sentry-symfony ### | |
SENTRY_DSN= | |
###< sentry/sentry-symfony ### |
SENTRY_DSN=https://7f45741877f3498eab0ae2bee6463d57@o372370.ingest.sentry.io/5186941 |
Now Symfony should be read from our dev
vault. Refresh... expand the object and... yes! All the values are null
! It works!
Let's try out production. Until now, to switch to the prod
environment, I've been updating the .env
file:
// ... lines 1 - 15 | |
###> symfony/framework-bundle ### | |
APP_ENV=dev | |
// ... lines 18 - 20 | |
###< symfony/framework-bundle ### | |
// ... lines 22 - 26 |
But now that we understand .env.local
, let's add APP_ENV=prod
there instead:
APP_ENV=prod |
Next, clear your cache:
php bin/console cache:clear
Then spin back to your browser and refresh. This time the dump is on top. If I expand it... yes! It's using the production values. Booya! That works because my project has the prod decrypt key. If that was not there, we would get an error.
Go ahead and take out the APP_ENV=
line in .env.local
to get back to the dev
environment:
APP_ENV=prod |
And in QuestionController
, let's cleanup: remove the dump()
, the new Exception
and the HubInterface
argument:
// ... lines 1 - 12 | |
class QuestionController extends AbstractController | |
{ | |
// ... lines 15 - 42 | |
public function show($slug, MarkdownHelper $markdownHelper) | |
{ | |
if ($this->isDebug) { | |
$this->logger->info('We are in debug mode!'); | |
} | |
$answers = [ | |
'Make sure your cat is sitting `purrrfectly` still ?', | |
'Honestly, I like furry shoes better than MY cat', | |
'Maybe... try saying the spell backwards?', | |
]; | |
// ... lines 54 - 62 | |
} | |
} |
After this... things are working again.
Overriding Secrets Locally
You are now ready to use Symfony's secrets system. But! The fact that environment variables take precedent over secrets is something that we can use to our advantage.
Find your terminal and run:
php bin/console secrets:list --reveal
In the dev
environment, the SENTRY_DSN
value is set to an empty string. Let's pretend that, while developing, I want to temporarily set SENTRY_DSN
to a real value so I can test that integration.
We could use secrets:set
to override the value... but that would update the secrets file... and then we would have to be super careful to avoid committing that change.
There's a better way. In .env.local
, set SENTRY_DSN
to the real value. Well, I'll put "FOO" here so it's obvious when this value is being used.
Now run that command again:
php bin/console secrets:list --reveal
The "Value" is still empty quotes, but now it has a "Local Value" set to the string we just used! The "Local Value" is the one that will be used. Why? Because our new environment variable overrides the secret: environment variables always win over secrets. This "Local Value" is a fancy way of saying that.
I'll take that value out of .env.local
so that my secret is once again used.
Next: let's have some fun! We're going to install MakerBundle and start generating some code!
Now that Knp markdown is abandoned I tried to implement the markdown caching service using the suggested twig filter. However that does not support/expose MarkdownParserInterface. I noticed that the twig filter uses michelf php-markdown though, which does support that interface. Luckily I did this in another branch which is now named 'broken' :( Autowiring does not pick up the michelf classes, do I need to put Michelf\Markdown in autoload.php? How do I stop twig from inlining the classes and making them disappear?