Running your application
The edge secret
The secret with which the edge proves to your containers that a request came through it, and how to replace it without a gap.
On this page
Scaleway routes a request on its Host header and only knows your container's own domain, so the edge sends that Host and carries the hostname the visitor asked for in a header of its own. Your application believes that header only together with a secret the edge adds to every request — the edge secret — and only for the domains of the environment. The visitor's address travels the same way: with the secret only the entry the edge appended to X-Forwarded-For counts, and a request without it loses the header altogether.
Brewless makes the secret when it sets an environment up, keeps it in your own Secret Manager, has the pull zone send it with every request, and gives it to the web container as BREWLESS_EDGE_SECRET on every deploy. You never see it and there is normally nothing to do with it.
What it protects
Someone who knows the secret and the address of your container at Scaleway can reach it directly and be believed: they can name any domain of your application as the visitor's hostname — on an application that gives every customer a subdomain, that is the subdomain of a customer — and put any address in X-Forwarded-For, which is what rate limits and your logs count. It is not a lock on the container: the container answers without the secret too, as itself.
So it is a shared secret, not a strong one. Your pull zone at bunny.net holds it in a rule, where anyone with the bunny.net key of your account can read it.
The realtime server is not behind the edge: browsers connect to its container directly, and it does not ask for the edge secret.
Replacing it
Replace it if it may have been seen by someone it should not have been — a key that leaked, a provider that reports an incident, someone who left.
brewless edge:rotate-secret production
The secret lives on two sides that cannot change at the same moment: a rule at the edge and a variable on your containers. Changing one and then the other would leave every request in between answered as the wrong host. Brewless therefore replaces it in a fixed order, with your containers holding both secrets for as long as that takes:
- It checks that your application can hold two secrets at once, which it says itself on its ops route.
- It writes a new secret to your Secret Manager, as a new version of the one that is there.
- It puts the image that is live now live again, and gives the containers the new secret together with the one the edge still sends. Nothing changes for a visitor.
- It points the rule at the edge to the new secret. Your containers hold it already, so this step is invisible.
- It puts the live image live once more, now with the new secret alone.
- It deletes the version of the secret the edge sent before, value and all.
That is two releases of the image that is live: nothing is built and nothing is rolled back, and your site keeps answering throughout. Each of those releases empties the edge cache, as every release does, so the pages come from your container once more before they are kept at the edge again.
Every step reads what is actually true at Scaleway and at bunny.net before it does anything, so a replacement that stopped halfway carries on where it left off, and one that is asked for twice replaces the secret once. Stopping anywhere leaves an environment that answers: either your containers accept both secrets, or the two sides agree on one. A deploy in between hands the containers the pair as well, and never moves the edge behind the replacement's back.
What it needs
brewless/laravel 1.2 or later in your application: that version reads a second secret from BREWLESS_EDGE_SECRET_PREVIOUS and counts it in full. An older version holds one secret at a time, and Brewless says so and changes nothing rather than leaving your site answering as the wrong host.
The environment also needs its variables kept through Brewless (brewless env:push at least once), because the new secret reaches the containers as a variable, and a worker or release container, because that is the container that answers whether the application can hold two secrets at once.
If you set BREWLESS_EDGE_SECRET in your variables yourself, that value wins and Brewless leaves the edge rule alone: the secret is then yours to keep in step on both sides. Replacing it is refused for such an environment, because moving the rule would point the edge at a secret your containers do not have. Take the variable out of your variables (brewless env:pull, remove the line, brewless env:push) and deploy; Brewless then keeps the secret in your Secret Manager and can replace it.