A signing secret per environment
Each application used to have one webhook signing secret for both environments. Now sandbox and production each have their own, and every delivery carries an X-Layout-Environment header of sandbox or live.
What changed
- Two secrets. Sandbox kept the secret it already had. Production was given a new one that is different from it.
- A header that names the environment, sent with
X-Layout-Signature,X-Layout-EventandX-Layout-Deliveryon every delivery, retries and replays included. - The Webhooks page follows the environment switch, showing the signing secret for whichever environment is selected. A test delivery is signed with that environment's secret.
Why it matters
Each environment now has its own signing secret, so trust in sandbox and trust in production are fully separate.
What to do
Copy the production signing secret from the Webhooks page into your production configuration, then pick the secret by the header before you verify:
const secrets = {
sandbox: process.env.LAYOUT_WEBHOOK_SECRET_SANDBOX,
live: process.env.LAYOUT_WEBHOOK_SECRET_LIVE,
};
const secret = secrets[req.headers["x-layout-environment"]];
if (!secret || !verify(req, secret)) return res.status(401).end();
verify is the signature check from Verify the signature. A handler that only ever sees one environment can keep a single secret, as long as it is that environment's.
Breaking changes
Yes, for production. A production handler still verifying with the old shared secret rejects every production delivery from this release on. Sandbox verification keeps working unchanged.