Secrets in code, pipelines and config files to HashiCorp Vault
Cohash finds secrets in repositories, CI variables, container images and config files and moves them into HashiCorp Vault. Workloads log in with Kubernetes, cloud IAM or pipeline OIDC, and static tokens go away. Database and cloud credentials become dynamic. Secret scanning with push protection stops new leaks. We rotate every exposed secret as well as moving it, because anything that sat in Git history has to be treated as compromised.
- 01Discovery
- 02Vault foundation
- 03Move and rotate by application
- 04Dynamic credentials
- 05Prevention
The story
Told without the client's name or anything that could identify them.
A financial services firm's platform team kept finding the same database password in new repositories, and its CI pipelines held long-lived cloud keys as project variables. Nobody could say which services would break if a key was rotated, so keys stayed as they were. We scanned repositories with full history, CI variables, container images and config stores, grouped the findings by credential and traced each one's users from logs. Then we built Vault on a supported 2.x release with Kubernetes, cloud IAM and pipeline OIDC logins. Secrets moved and were rotated application by application, databases and cloud accounts switched to dynamic credentials, and push protection now blocks new leaks at commit time.
why it was urgentSecret leakage sits at number two on OWASP's 2025 Non-Human Identities Top 10. Vault 2.0 went generally available on 14 April 2026, now on IBM's support cycle, and 2.2.0 followed on 15 October 2026. On the GitHub side, Secret Protection, which includes push protection, has been a separate product since 1 April 2025.
- openSecret scanning keeps finding the same database password in new repositories.
- recurringCI pipelines hold long-lived cloud keys as project variables.
- blockedThe apps still read one static password out of the same config file they've been using for years.
- openNobody knows which services break if a given API key is rotated.
The estate, before and after
Before: static secrets spread across code, CI and config
Passwords and keys lived in repositories, CI variables and config files, and several services shared the same credential. Nobody rotated them because nobody knew who else depended on each one.
Read the diagram as text
- Git repositories → Applications and services: hardcoded password
- Config files and images → Applications and services: static secret
- CI project variables → Deploy pipelines: long-lived key
- Applications and services → Databases: shared login
- Deploy pipelines → Cloud accounts: static keys
- Applications and services → Third-party APIs: shared API key
After: workloads get credentials from HashiCorp Vault at run time
Each workload authenticates with its platform identity and gets a short-lived credential from Vault. We keep Vault policies in Terraform, and push protection keeps new secrets out of Git.
Read the diagram as text
- Git repositories → CI pipelines: clean commits
- CI pipelines → HashiCorp Vault 2.x: JWT/OIDC login
- Kubernetes workloads → HashiCorp Vault 2.x: Kubernetes auth
- Vault policies in Terraform → HashiCorp Vault 2.x: policies
- HashiCorp Vault 2.x → Databases: dynamic credentials
- HashiCorp Vault 2.x → Cloud accounts: short-lived credentials
- HashiCorp Vault 2.x → Third-party APIs: rotated API key
How we run it, phase by phase.
5 phases take you from Secrets in code, CI variables and config files to HashiCorp Vault 2.x. Each one ends with something you can check before the next starts. As you scroll, the blocks show the estate moving across.
- phase 01
Discovery
Scan repositories, history included, plus CI variables, container images, infrastructure code and shared config stores. Group findings by secret instead of by file. Tie each one to an owner and the systems it opens.
- phase 02
Vault foundation
We put the cluster on a supported 2.x release, with auto-unseal, audit devices and Terraform-managed policies. Auth methods come before anything else: Kubernetes, cloud IAM, and JWT/OIDC from the pipeline provider.
- phase 03
Move and rotate by application
For each application, store the secret in Vault, change the code or Vault Agent template to read it, rotate the old value and remove it from config. Rotation proves nothing still uses the copy in Git.
- phase 04
Dynamic credentials
If the target supports it, we swap the static database and cloud credentials for dynamic ones from Vault's secrets engines. Every workload gets its own login, and it expires.
- phase 05
Prevention
Turn on push protection and pre-commit scanning, alert on new findings and agree who rotates a leaked secret within what time.
What the client got
What changed for the client once the work was done. Described, not scored: we don't publish client figures.
- result 01
Every secret has an owner and a known blast radius
We grouped the inventory by credential, not file. Every entry names an owner and the systems that secret can open.
- result 02
Copies left in Git history no longer work
We rotated each secret as it moved into Vault. That also proved nothing was still reading the old value out of a config file.
- result 03
Workloads log in with platform identity
Kubernetes service accounts, cloud IAM roles and pipeline OIDC tokens authenticate to Vault, so no static Vault token sits in a CI variable.
- result 04
Databases and cloud accounts issue short-lived logins
We switched on the database and cloud secrets engines where the target supports them. Each workload now has its own credential, and it expires on its own.
- result 05
New leaks are stopped at push
We turned on push protection and pre-commit scanning to block secrets before they land, and wrote a runbook naming who rotates a leaked secret and how quickly.
Risks we plan for
-
Moving without rotating
Copying a secret into Vault doesn't help if the old value still works from Git history. We rotate every one we move.
-
Shared credentials with unknown users
One API key often serves five services. Rotate it and four you didn't know about break, so we trace usage in logs first.
-
Vault becomes the outage
If every service depends on Vault, Vault needs DR replication or a tested snapshot restore. That work is part of the plan, not an afterthought.
-
Static tokens to reach Vault
Replacing a password with a long-lived Vault token in the same CI variable moves the problem. Workloads use platform identity to log in.
Where AI helps, and where it needs guardrails
Vault 2.1.0 made Agentic IAM generally available as an Enterprise feature, issuing short-lived, scoped credentials to AI agents. We also treat coding assistants and MCP clients as a new leak path: MCP server configs often hold API keys in plain JSON, and assistants paste secrets into prompts and commits. Agents get credentials from Vault at run time for one task, and secret scanning covers agent-written code like any other.
forward deployed engineers →What you're left with
We write these for your setup, and they're working documents. Your team should be able to keep things running from them long after we've gone.
- inventory01
Secret inventory grouped by credential, owner and blast radius
yours to keep - code02
Vault auth methods and policies as Terraform, reviewed by pull request
yours to keep - document03
Per-application migration and rotation record
yours to keep - document04
Dynamic credential setup for databases and cloud accounts
yours to keep - runbook05
Push protection and leak-response runbook
yours to keep
Platforms and services on this move
Services involved
Certified engineers, wherever you need them.
Some clients want a project team, some want a couple of engineers on theirs. Either works. Onsite, nearshore or offshore, with handovers across time zones that keep things moving.
Onsite
Engineers at your sites in the US
Nearshore
Overlapping hours with US teams
Offshore
Overnight progress on your backlog
All time zones
Coverage handed over across time zones
01Vault, a cloud secret manager or our PAM tool?
Depends on your clouds and what you already pay for. Vault is strongest across multiple clouds and on-premises, and for dynamic credentials. On one cloud, the native secret store may be simpler. Human admin access often sits better in a PAM tool like CyberArk. Plenty of companies use two of these, with a clear boundary.
02Do we need Vault Enterprise?
Only if you need namespaces, replication or Agentic IAM. Community Edition covers a lot of migrations, so we work out what you really need before anyone talks licences.
03How long does this take?
It depends on the number of applications, how many share credentials and how much code needs changing to read from Vault. Discovery gives a count of distinct secrets and owners, and the plan follows from that.
04What about secrets already in Git history?
Rewriting Git history is optional, and it's disruptive. Rotation isn't optional. Once a secret is rotated, the old value in history opens nothing.
Often on the same roadmap
On-premises Active Directory to cloud-first Microsoft Entra ID
We shrink on-premises Active Directory one application at a time, moving groups, users and app authentication to Microsoft Entra ID as each app is ready.
read the case studyAD FS federation to Entra ID authentication
Converting federated domains from AD FS to Entra ID cloud authentication, moving relying parties app by app and retiring the AD FS farm.
read the case studyApache Airflow 2 to Airflow 3
Upgrading self-managed Apache Airflow 2, now past end of life, to Airflow 3, and fixing removed features, auth and scheduling changes before DAGs move.
read the case studyc25d9e85 - 01InfoQ: Vault 2.0 under IBM (24 Apr 2026)infoq.com ↗
- 02HashiCorp: Vault release notes (2.1.0 and 2.2.0)developer.hashicorp.com ↗
- 03GitHub changelog: Introducing GitHub Secret Protection and GitHub Code Security (4 Mar 2025)github.blog ↗
- 04OWASP: Non-Human Identities Top 10 for 2025owasp.org ↗
- 05HashiCorp Developer: Vault database secrets enginedeveloper.hashicorp.com ↗
Planning this move?
A 30-minute working session with a senior engineer. No slides.
- The platform and the version you're on
- Where you need to get to, and by when
- What's custom: rules, plugins, integrations
- Any audit finding or deadline driving it