Where Secrets Live: From Config Files to Vault

You are setting up a new application. You create a .env file with database credentials, API keys, and server addresses. It works on your machine. You commit it to Git so your teammate can run the same setup. A few months later, the application is in production, and someone accidentally pushes that .env file to a public repository. Within minutes, your production database password is on the internet.

This scenario is not rare. It happens because the simplest way to store secrets is also the most dangerous. The journey from storing secrets in config files to using dedicated secret management tools is one that every team goes through, often after learning the hard way.

The Problem with Config Files

When you first learn to build applications, putting everything in one configuration file feels natural. Your .env, config.json, or application.properties becomes a mixed bag. Server addresses that are not sensitive sit next to database passwords that are extremely sensitive. The whole file goes into Git, and anyone with repository access can see everything.

This approach works fine when you are the only developer and the application runs on your laptop. But as soon as your team grows or the application reaches real users, the cracks appear. Every developer who clones the repository can see production passwords. Even if the repository is private, secrets are permanently stored in Git history. Deleting the file from the latest commit does nothing to remove it from older commits. The secret is there forever, accessible to anyone who knows how to browse Git history.

The next step most teams take is separating secrets from regular configuration. The config file stays in Git, but sensitive values become placeholders like DB_PASSWORD=changeme. The real values live elsewhere: a file that is not committed, environment variables on the server, or a document shared through chat. This is better than storing secrets in Git, but it introduces new problems. There is no record of who accessed the secret. Rotating a password means updating it in multiple places manually. If the secret file gets lost or corrupted, there is no managed backup to restore from.

What a Dedicated Secret Store Changes

Teams that deal with multiple applications and environments eventually look for tools built specifically for secrets. Vault, AWS Secrets Manager, Azure Key Vault, and GCP Secret Manager are designed to handle sensitive data properly. Secrets are no longer files on disk. They become objects that applications retrieve through an API.

The shift from files to a secret store changes three fundamental things:

Here is a quick example of how you would store and retrieve a database password using HashiCorp Vault:

# Store a secret
vault kv put secret/myapp DB_PASSWORD=supersecret

# Retrieve the secret
vault kv get secret/myapp

# Output:
# ====== Data ======
# Key              Value
# ---              -----
# DB_PASSWORD      supersecret

Access control. With a config file, anyone who can read the file can see the secret. With a vault, you define which application or pipeline can access which secret. A CI pipeline for the staging environment can retrieve staging credentials but cannot touch production secrets. This granularity is impossible with files.

Audit trail. Files do not log who read them. A vault records every access request: who asked, what secret they requested, and when it happened. If a secret leaks, you can trace which applications or users accessed it around the time of the incident.

Encryption at rest and in transit. Config files store secrets in plain text on disk. A vault encrypts secrets when storing them and when sending them over the network. Even if someone gains access to the underlying storage, they cannot read the secrets without the encryption keys.

The Operational Cost of Using a Vault

Secret management tools are not free, and the cost is not just monetary. Your team needs to learn how to operate the tool. If the vault goes down, applications cannot fetch secrets and may stop working entirely. You need strategies for high availability, caching, or fallback mechanisms so that a vault outage does not take down your production system.

Cloud-managed secret stores reduce the operational burden but introduce per-request or per-secret pricing. A team making thousands of secret requests per minute needs to consider whether the cost is sustainable. Self-hosted options like Vault give you more control but require dedicated effort to maintain, upgrade, and secure.

Choosing What Fits Your Team

There is no single right answer for where to store secrets. The right choice depends on your team size, number of applications, and risk tolerance.

The following flowchart can help you decide which approach fits your current situation:

flowchart TD A[Start: How many apps and developers?] --> B{Team size & complexity} B -->|Small team, one app| C[Use .env file not committed to Git] B -->|Growing team, multiple apps| D[Use environment variables from CI] B -->|Large team, regulated| E[Use dedicated vault e.g. HashiCorp Vault] C --> F[Risk: manual rotation, no audit] D --> G[Better: central config, some audit] E --> H[Best: access control, audit, encryption]

A small team with one application and a handful of environments can use a separate file that is not committed to Git, as long as everyone understands the risks. The key is being deliberate about the choice, not falling into it by default.

A team with multiple applications, several environments, and multiple developers will benefit from a dedicated secret store. The overhead of setting it up pays for itself the first time you need to rotate a credential across all environments or investigate who accessed a secret that later leaked.

The important principle is consistency. Whatever method you choose, apply it uniformly. Mixing approaches, some secrets in files, some in environment variables, some in a vault, creates confusion and increases the chance of accidental exposure.

Practical Checklist for Secret Storage

  • Are secrets separated from regular configuration?
  • Are secrets excluded from version control (check .gitignore)?
  • Can you rotate a credential without changing application code?
  • Do you know which applications and pipelines can access each secret?
  • Do you have logs showing who accessed a secret and when?
  • If your secret store goes down, can your application still start or fail gracefully?

What Comes Next

Knowing where to store secrets is only half the work. The next question is how your pipeline retrieves those secrets without storing them inside the pipeline configuration itself. A CI/CD pipeline that prints secrets to logs, stores them in environment variables visible to all steps, or caches them in workspace files is no better than a config file committed to Git. The storage method matters, but how secrets flow through your delivery process matters just as much.