Build-time secrets are still secrets
Static output is reassuring: there is no runtime, so there is nothing to compromise at runtime. The build is a different story.
The three ways it goes wrong
- The key gets a public prefix. Every framework has one —
PUBLIC_,NEXT_PUBLIC_,VITE_— and it means "inline this into the browser bundle". Renaming a variable is enough to publish a credential. - The key gets committed. Usually in a
.envthat was never added to.gitignore. - The key is over-scoped. A read-only delivery key that leaks is an inconvenience. A management key that leaks is an incident.
What to do about it
Use the narrowest scope that can build the site. Keep write-capable keys off CI entirely — if seeding needs one, run it from a laptop. And grep your build output for the key before you trust the setup, because that check takes five seconds and assumptions do not.