Why Your Database Password Should Never Live in a Config File
You are building a new application. Early on, you put all the variable data into one file: database name, server address, API URLs. It goes into Git, gets pushed to the repository, and gets deployed to the server. Everything is in one place, and it feels practical. Then you add a database password to that same file. Then an API token. Then an encryption key. Suddenly, that single config file becomes a security risk that could bring down your entire system.
This is the moment when you realize that not all configuration data is the same. Some data, if exposed, gives someone else the keys to your kingdom. That data is called a secret. And treating secrets like regular configuration is one of the most common and dangerous mistakes teams make.
The Difference Between Config and Secret
Regular configuration data includes things like server names, application ports, or feature flags. If someone outside your team knows your application runs on port 8080, that is not a disaster. They cannot log into your database just because they know the port number.
Secrets are different. A database password, an API token, or an encryption key can be used by an attacker to impersonate your system, access your data, or destroy your infrastructure. The impact of a leaked secret is immediate and severe.
Yet many teams still treat secrets as if they were regular config. They put passwords in .env files and commit them to Git. They store API tokens in application config files and push them to the repository. They keep SSH keys inside project folders and back everything up to the cloud. This is not because the team is careless. It is usually because they have not yet experienced the consequences.
What Happens When a Secret Leaks
In 2022, several high-profile incidents involved AWS tokens left in public repositories. Attackers used those tokens to spin up cryptocurrency mining instances. The bills ran into tens of thousands of dollars in hours. In other cases, leaked database passwords led to customer data being downloaded and sold on the dark web.
These incidents did not start with a sophisticated attack. They started with a simple mistake: treating a secret like a config file. The secret was there, visible to anyone who could access the repository. Once the repository was public, the secret was public too.
Git history makes this worse. Even if you delete a file that contained a secret, the secret remains in the commit history. Anyone who clones the repository can run git log and find the password you thought you removed. There is no easy way to scrub Git history completely, especially if the repository has been shared or forked.
How Config and Secrets Differ in Practice
The differences between config and secrets affect how you handle them in your daily work and in your CI/CD pipeline.
Who can see them: Config can be visible to all developers on the team. Secrets should only be visible to people or systems that absolutely need them. Not every developer needs to know the production database password.
Where they are stored: Config can live in Git. Secrets must never be stored in Git. They belong in a dedicated secret storage system that encrypts them at rest and in transit.
How they are rotated: Config rarely needs to be rotated. You change a server name when you migrate infrastructure, and that is it. Secrets need regular rotation. You should rotate database passwords every few months, and rotate immediately if there is any indication of a leak.
How pipelines handle them: In a CI/CD pipeline, config can be read directly from a file in the repository. The pipeline takes the file and uses it. Secrets require a different approach. The pipeline must fetch them from a secure storage system, inject them into the build or deploy process, and ensure they never appear in logs, artifacts, or deployed files.
The Practical Consequences of Confusing the Two
When you treat secrets like config, you create a chain of problems that are hard to undo.
First, you lose control over who has access. If the secret is in Git, anyone with repository access has the secret. That includes contractors, former employees who still have access, and potentially attackers if the repository is public.
Second, you make rotation difficult. If the secret is scattered across multiple config files, branches, and deployment environments, rotating it means finding every copy and updating it. You will inevitably miss one, and that old password will remain valid somewhere.
Third, you break your audit trail. If a secret leaks, you need to know who had access and when. If the secret was in Git, the answer is "everyone who ever had repository access." That is not a useful audit trail.
A Simple Way to Tell the Difference
Before you put any data into a config file, ask yourself one question: "If someone outside my team sees this, can they use it to access my system?"
If the answer is no, it is probably config. Server names, port numbers, feature flags, and log levels are config.
If the answer is yes, it is a secret. Database passwords, API tokens, SSH keys, encryption keys, and service account credentials are secrets.
This simple test will prevent most of the common mistakes teams make.
Practical Checklist for Handling Secrets
When you set up your next project or review your current one, run through this checklist:
- Are all secrets stored outside Git? Use a dedicated secret manager or vault.
- Are secrets injected at runtime, not baked into images or artifacts?
- Do your CI/CD pipelines fetch secrets from a secure source, not from repository files?
- Are secrets excluded from logs, error messages, and debug output?
- Do you have a rotation schedule for each type of secret?
- Is there a process for rotating secrets immediately when a leak is suspected?
- Can you revoke access to secrets for specific people or systems without affecting others?
The Takeaway
If a piece of data can be used by someone else to impersonate you or your system, it is not configuration. It is a secret. Treat it differently. Store it separately. Rotate it regularly. And never, ever commit it to Git. The cost of learning this lesson the hard way is far higher than the effort of doing it right from the start.