Where your secrets should actually live
Codexa Engineering · Oct 4, 2026 · 2 min read
Credential handling is unglamorous, rarely prioritised, and the cause of a disproportionate share of serious incidents. The good practice is not complicated — it is just rarely written down.
Never in the repository
This is the one everyone knows and it still happens constantly, usually via a config file committed before `.gitignore` was set up.
Crucially, deleting the file does not fix it. Git keeps history, so a secret committed once remains readable to anyone who can clone the repository. The only real remedy is to rotate the credential, and then optionally rewrite history.
One file, restricted, outside the build
For a self-hosted application, a single environment file owned by the service user with `600` permissions is a perfectly good answer.
- Not readable by other users on the box.
- Not in the repository, and not deployed from it.
- Not duplicated into a process manager's config, where it ends up in a dump file.
That last point matters more than it sounds: listing secrets in a process manager's ecosystem file means they are written to its state dump, which is a second copy with different permissions that nobody remembers to protect.
Keep an example file, with blanks
A committed example listing every variable name with empty values is genuinely useful: it documents what the application needs, and it makes a missing variable obvious rather than mysterious.
It must never contain real values, including ones you consider harmless.
Rotate when people leave
Any credential a departing person could have read should be rotated, regardless of circumstances. This is procedural rather than technical and it is the step most often skipped.
Making rotation easy is what makes it happen: a credential that takes an afternoon to rotate will not be rotated.
What do I do if a secret is committed?
Rotate it immediately — that is the only step that actually closes the exposure. Treat the credential as compromised from the moment it was pushed, because you cannot know who cloned the repository in between. Rewriting history is optional cleanup afterwards; it is not a substitute for rotation, and doing it first wastes the time that matters most.
Are environment variables secure enough?
For most applications, yes, provided the file they come from is properly restricted and never committed. A dedicated secret manager adds audit logging, automatic rotation and fine-grained access, which earn their complexity in regulated environments and larger teams. For a small team running one or two services, a correctly permissioned file is not a compromise — it is proportionate. For the wider running costs this sits inside, see what software costs to run.
Enjoyed this? Let's work together.
Start a project