a green build and clean merge can still miss the user path; if nobody walked it live, the feature was not shipped yet.
2026-06-17
Moving every secret into one canonical store made our env files boring again
Moving secrets into one canonical store made env files boring again and made rotation and drift easier to manage.
The clearest fix we made was moving every secret out of app env files and into one canonical store. Credentials now load at runtime instead of living inside project files, and that one change cleaned up a lot of the mess around how we handled configuration. The part that matters is simple: the app asks for credentials when it runs, while the files in the repo go back to being plain configuration. That shift sounds small on paper. In practice, it changes how a solo developer can move across projects without carrying hidden risk everywhere.
Before that change, drift was the tax we kept paying. Each project had its own env file, and the real question became which one held the current value. That turns into archaeology fast. You stop trusting the shape of your setup because every copy can slowly diverge from the others. Once there is one source of truth, that problem gets much smaller. There is a single place to update, a single place to reason about, and a much lower chance that one app is quietly running with a different value than the rest.
Rotation is where the new setup really pays off. When a credential changes, swapping it in one place means every app picks it up the next time it loads at runtime. There is no need to grep across repos or replace values file by file. That matters because rotation is where bad habits usually show up. The old workflow made every change feel broad and fragile, which is exactly when people delay it. A runtime load path makes the update feel local. The move is contained, and the blast radius stays small.
The other win was that secrets stopped leaking into code and config. Once sensitive values are out of project files, there is much less chance that something private gets committed by accident or copied into a place it should never have reached. That is the kind of cleanup that does more than remove a risk on a checklist. It changes what the rest of the repository can safely contain. You can look at the files again without wondering whether they hide something that should have stayed elsewhere.
What nobody tells you is that the store itself is only part of the story. The bigger change is that env files become boring again. They go back to being just config. You can read them. You can share the shape. You can commit a template. None of that feels dangerous anymore, because the sensitive values are gone from the file. That boring quality is the real sign the system is healthier. When the file stops carrying secrets, it becomes easier to reason about, easier to review, and easier to hand to someone else without adding extra caution to every glance.
We ran config-with-secrets-inline for a long time and told ourselves it was fine because it worked. It worked the way a bald tire works, right up until rotation day. That is the lesson I keep coming back to. A setup can function for a long stretch and still carry a failure mode that only shows itself when you need to change something important. The safer rule is to keep secrets out of project files and load credentials at runtime from one canonical store. If you are still copying values into `.env` files project by project, this is the place to stop and ask what your real source of truth is.
If you want to apply the same idea, start with your current credential path and trace where each value lives today. Ask whether the file in the repo is carrying sensitive data or just describing configuration shape. Then move the sensitive part into one runtime source and leave the file behind as a template you can read without concern. That gives you cleaner rotation, less drift, and a setup that stays understandable after the first pass is over. For a solo builder, that kind of simplicity is worth more than a setup that only looks convenient while nothing changes.
production verification belongs in the definition of done, because the live check is where the answer shows up.
A single source of truth keeps repos, services, access details, and automations in sync by updating the record with the change.